Thanks Scott,
Now that you mentioned it, I do recall the issue with returning a 1 byte char field to CL from RPGLE proc.
Since this was more of a can I do this for myself, I will not be changing any programs.
Your explanation was exactly what I needed.
Jeff Young
Sr. Programmer Analyst
IBM -e(logo) server Certified Systems Exper - iSeries Technical Solutions V5R2
IBM Certified Specialist- e(logo) server i5Series Technical Solutions Designer V5R3
IBM Certified Specialist- e(logo)server i5Series Technical Solutions Implementer V5R3
----- Original Message ----
From: Scott Klement <midrange-l@xxxxxxxxxxxxxxxx>
To: Midrange Systems Technical Discussion <midrange-l@xxxxxxxxxxxx>
Sent: Wednesday, February 27, 2008 3:59:23 PM
Subject: Re: Call Service Pgm Proc from CL
Hi Jeff,
I am attempting to call a procedure in a service program from a CLLE pgm.
The CLLE pgm source is:
DCL VAR(&PICK_TYPE) TYPE(*CHAR) LEN(1)
CALLPRC PRC(GET_WMS_PICK_TYPE) PARM((&CMPA *BYVAL) +
(&LOC *BYVAL) (&AREA *BYVAL) (&EOJ +
*BYVAL)) RTNVAL(&PICK_TYPE)
Remove all of the *BYVAL stuff from your CL command. The RPG prototype
shows that the parameters are being received by reference not value. If
you don't pass them from the CL the same way, you'll get the dreaded
"unpredictable results" of stomping on memory. Not only that, but your
parameters will almost certainly not work. :) Having said that, it's
not what's causing the MCH3601...
The 1A return value is what's giving you grief. Under the covers, RPG
and CL use different mechanisms for returning a 1-byte character field.
CL (and also C) pass it as a 8-bit integer. RPG (and also COBOL) pass
it as a character string that's only one character long. Because of
these differences, any time you return a 1A (or 1N or 3I 0, or 3U 0)
from an RPG subprocedure and call it from CL, you'll get this error.
This is a FAQ, by the way.
There are two ways to fix it... On your RPG prototype (on the PR, not
the PI), you can specify EXTPROC(*CL). In your example, this would make
your prototype look like this:
D Get_WMS_Pick_Type...
D PR LIKE(##FLAG)
D EXTPROC(*CL:'GET_WMS_PICK_TYPE')
D Company LIKE(##CMPA) CONST
D Location LIKE(##LOC) CONST
D Area LIKE(##BINAREA) CONST
D EOJ_Flag LIKE(##FLAG) CONST
D Options(*NoPass)
This tells the RPG compiler that it should use the CL language's
parameter passing conventions. Therefore, it'll pass the 1A field the
way the CL program expects, and you won't get an error.
Warning: Using the above technique will require you to re-compile and
re-bind any existing RPG code that calls this procedure. Any existing
callers need to be recompiled so that THEY TOO use the alternative
parameter passing mechanism.
If you don't want to re-compile and re-bind all of the existing callers,
then you can use this alternative:
DCL VAR(&TEMP) TYPE(*CHAR) LEN(2)
DCL VAR(&PICK_TYPE) TYPE(*CHAR) LEN(1)
CALLPRC PRC(GET_WMS_PICK_TYPE) PARM((&CMPA *BYVAL) +
(&LOC *BYVAL) (&AREA *BYVAL) (&EOJ +
*BYVAL)) RTNVAL(&TEMP)
CHGVAR VAR(&PICK_TYPE) VALUE(%SST(&TEMP 1 1))
You see, CL only passes the return value as a numeric field if it's
1-character long. If it's two characters or more, it passes it as a
character field. Since RPG always passes as character field (unless you
use EXTPROC(*CL) that is) this'll make them compatible.
What I did was code the return value as a *CHAR 2 in the CL program.
The RPG program can stay unchanged. This way, the RPG procedure will
only change the first of the two characters in my &TEMP variable... but
other than that, it'll work. So I use %SST to extract only that first
character...
Anyway, these two solutions are alternatives... don't make the mistake
of thinking that you have to use them both.
Just pick one or the other. I recommend using EXTPROC(*CL) since it's
more self-documenting -- but if EXTPROC(*CL) would require re-compiling
a lot of existing code, I'd use the *CHAR 2 solution instead to avoid that.
As an Amazon Associate we earn from qualifying purchases.