|
Hi Charles,
You're right. This quote from that thread implies the problem is with 1-byte parameters, but doesn't say exactly what the problem is.
"This is a "feature". Because CL differs from RPG in the way it passes
parameters, you must take explicit action to prevent problems passing
1-byte parameters between CL and RPG when using CallPrc."
Further in the thread, Barbara Morris says
"You can use *CL, *CWIDEN, *CNOWIDEN, *JAVA both for other-language
procedures called by RPG and RPG procedures called by CL, C or Java.
They control the way certain types are returned and passed by value, in
either direction."
which implies it's a difference in the way parameters are passed by value, but doesn't really clarify.
On another post (https://www.ibm.com/mysupport/s/question/0D50z00006LKofY/wrong-value-in-parm-by-value-called-from-cl?language=en_US), Barbara said
"I know that the system has different ways of handing various data types passed by
value. I don't know the details, but it looks like zoned and character are handled differently.
So even though the actual zoned parameters are coming across correctly, the difference in
handling between zoned and character is affecting the character parameter following the
zoned parameters."
I was unable to find anything that explained the actual differences in how the parameters are passed. I wrote a couple of programs to test it.
TESTPARMC (CLLE)
PGM (&FROMRPG)
DCL VAR(&FROMRPG) TYPE(*CHAR) LEN(1)
SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) +
MSGDTA('Received |' *CAT &FROMRPG *CAT +
'|') TOPGMQ(*EXT)
DMPCLPGM
ENDPGM
TESTPARMR (RPGLE)
h option(*nodebugio: *srcstmt)
d TESTPARMC pr extproc('TESTPARMC')
d parm 1a
d TESTPARMI pr extproc('TESTPARMC')
d parm 1n
d TESTPARMCc pr extproc('TESTPARMC')
d parm 1a const
d TESTPARMIc pr extproc('TESTPARMC')
d parm 1n const
d TESTPARMCv pr extproc('TESTPARMC')
d parm 1a value
d TESTPARMIv pr extproc('TESTPARMC')
d parm 1n value
d toCL_char s 1a inz('A')
d toCL_ind s 1n inz('1')
TESTPARMC(toCL_char);
TESTPARMI(toCL_ind);
TESTPARMCc('B');
TESTPARMIc(*off);
TESTPARMCv('C');
TESTPARMIv(*off);
eval *inlr=*on;
CALL TESTPARMR
Received |A|
Received |1|
Received |B|
Received |0|
Received |0|
Received |0|
And from the program dumps:
Variable Type Length Value Value in Hexadecimal
*...+....1....+....2....+ * . . . + . . . . 1
&FROMRPG *CHAR 1 'A' C1
&FROMRPG *CHAR 1 '1' F1
&FROMRPG *CHAR 1 'B' C2
&FROMRPG *CHAR 1 '0' F0
&FROMRPG *CHAR 1 '0' F0
&FROMRPG *CHAR 1 '0' F0
My understanding is that when RPGLE is passing a parameter by value, it allocates new storage and makes a copy of the value, and passes a pointer to that copy. If that were the case, I don't see why it would be any different than passing a pointer to the defined variable. Maybe it passes it on the stack instead of a pointer, or in a register or something, and the CL doesn't look there.
My takeaway is that as long as you're NOT using the CONST or VALUE keyword on a prototyped parameter that's being passed to a CL, you're ok. If you use CONST, maybe it works, maybe it doesn't. In my test it worked, but CONST *might* work the same as VALUE (making a copy of the value and passing a pointer to that copy) in some cases, so I'm not sure.
--
*Peter Dow* /
Dow Software Services, Inc.
909 793-9050
petercdow@xxxxxxxxx <mailto:petercdow@xxxxxxxxx>
pdow@xxxxxxxxxxxxxx <mailto:pdow@xxxxxxxxxxxxxx>
/
On 8/5/2021 12:58 PM, Charles Wilt wrote:
On Thu, Aug 5, 2021 at 1:51 PM Peter Dow <petercdow@xxxxxxxxx> wrote:
I think this thread covers it:Not so much, no details on what's different. As I said originally, just
https://archive.midrange.com/rpg400-l/200209/msg00333.html
the "fix".
Charles
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.