× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



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:

https://archive.midrange.com/rpg400-l/200209/msg00333.html


Not so much, no details on what's different. As I said originally, just
the "fix".

Charles


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

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.