Hello,

First, please make the distinction between passed by value vs. passed by reference.   The difference between how RPG and CL pass one byte variables only applies to parameters passed by value. When passing by reference, this is a non-issue.

The OP was calling a CL procedure from RPG.   CL does not accept input parameters (*ENTRY parameters) by value, it only knows how to receive input parameters by reference... so this is a non-issue for this thread.

For things passed by value (i.e. using CALLPRC with RTNVAL or a PARM with *BYVAL specified, you would need to specify *CL (or *CWIDEN/*CNOWIDEN since C procedures work the same way as CL procedures) on the RPG prototype's EXTPROC.  This will cause RPG to use the CL convention for 1 character variables.

Parameter passing is done by putting data onto a stack.  When you pass data by reference, it puts the memory address on the stack (you referred to this as "a pointer", which is very close to the same thing... technically a pointer is a variable used to store an address, and its the address that's placed on the stack, not the variable that stores it.)  When you pass by value, it puts the variable's value (the raw bytes that make up the variable) onto the stack.

It does not "allocate memory and then pass a pointer" -- you're thinking of CONST, here.

-SK


On 8/5/2021 6:21 PM, Peter Dow wrote:
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.