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



Scott,
Once Charles told me about EXTPROC, I did a Google search and came
across http://archive.midrange.com/midrange-l/200312/msg00783.html. It
is one of your old post with an example of how to set up the prototype
using EXTPROC so, thanks twice. ;-) Once for the old post and once for
the new one. Both are now in my "gotcha" folder.


Terry Anderson
Programming Manager
Citation Corporation
Switchboard 1.251.867.5481 ext 212
Direct Line 1.251.809.2312
Fax 251.867.0525
Cell 1.251.363.4975


message: 4
date: Tue, 04 Dec 2007 12:25:10 -0600
from: Scott Klement <midrange-l@xxxxxxxxxxxxxxxx>
subject: Re: Strange behavior when calling subprocedure from CL.

Hi Terry,

It has to do with differences in the way RPG and CL
interpreted the ILE
spec. ILE CL and ILE C both pass 1 character return values
as binary
integers. They use C's widening rules, etc. However, when
the return
values are 2 bytes or larger they are passed as character strings.

ILE RPG and COBOL, however, always pass them as character strings
(which, somewhere under the covers, uses a pointer and
that's where your
error comes from.)

RPG has EXTPROC keywords for the prototype that change this
behavior.
If you specify EXTPROC(*CL:'MYPROCNAME') or
EXTPROC(*CWIDEN:'MYPROCNAME') RPG will change it's passing
convention to
match that of C or CL, and that will solve the problem.
However, if
you do this, you need to recompile and rebind any existing
RPG code that
calls the service program so that they, too, will use the
new parameter
passing method.

If changing the callers to use EXTPROC is too big of a
hassle (For me,
it has been for several service programs -- I don't want to
change 2500
calling routines!) there's a workaround on the CL side of things.

Just declare the return value as being two characters instead of one:

DCL VAR(&TEMP) TYPE(*CHAR) LEN(2)
DCL VAR(&RTNVAL) TYPE(*CHAR) LEN(1)

CALLPRC PRC(MYPROC) RTNVAL(&TEMP)
CHGVAR VAR(&RTNVAL) VALUE(%SST(&TEMP 1 1))

Because character variables that have a length of 2 (or higher) are
passed as character strings in CL (just like RPG) the preceding code
will not cause the pointer error. Even though the RPG
program returns
only 1 char, the CL program receives two, making them
compatible. You
then use %SST to ignore the 2nd character, since it serves
no purpose
(other than making the calling convention compatible.)

Again, you don't have to use this workaround if you use
EXTPROC(*CL:'MYPROC') on the RPG side. EXTPROC(*CL is, IMHO, more
elegant because the "next guy" will find it easier to read and
understand and can go to the manual to see what it does. But in a
situation where you can't change the RPG side without breaking
compatibility, using the 2-char CL rtnval approach makes things work
properly without changing the RPG end of things.




As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

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.