× 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.



Thanks Scott...

Interesting that the RPG Manual doesn't say anything about *BYVAL

EXTPROC(*CL:name)Specifies an external procedure that is written in ILE CL,
or an RPG procedure to be called by ILE CL. Use *CL if your program uses
return values with data types that CL handles differently from RPG. For
example, use *CL when prototyping an RPG procedure that is to be called by
a CL procedure when the return value is 1A.


But what is the actual difference between how CL & RPG handle a 1 byte
*BYVAL and/or *RTNVAL parm?

Charles

On Thu, Aug 5, 2021 at 6:44 PM Scott Klement <midrange-l@xxxxxxxxxxxxxxxx>
wrote:

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

--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/midrange-l.

Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription related
questions.

Help support midrange.com by shopping at amazon.com with our affiliate
link: https://amazon.midrange.com


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.