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



> I've tried to find this on the web and in the archives, but all I can
> find is RPG calling C, not the other way around.

There aren't as many C programmers on the iSeries as there are RPG
programmers, that's why.  Since IBM writes all of the APIs in C, and we
call them from RPG, the topic of RPG calling C comes up quite often.


> I can't find ANYTHING on the way parms are handled in each language.
> (I thought I'd read that RPG always passes by reference, but C by
> default passes by value, but I can not seem to be able to verify that.)

Depends.  Are we talking about calling a program or a procedure?  When
calling a program (no matter what language) parameters are always by
reference.

When calling a procedure, an RPG programmer has a choice -- but it's
reference if you do not specify "value".   On the other hand, pretty much
everything is passed by value in C.  If you want to pass by reference in
C, you pass a pointer.

> In 'C' I'd have to allocate memory to return a value, else the associate
> memory goes away when the call is over and would give me such an MCH3601
> error.

That's not true.  You do not have to allocate a memory to return a value.
You have to allocate memory if you want to return a pointer to it, but
that's also true in RPG...

Take the following procedure (or "function" in C-speak):

int someproc(void) {
   return 15;
}

I did not have to allocate anything, and it returned a value.  I won't get
an MCH3601.  What you're probably thinking of is returning a character
string.  For example, the following would cause a nasty problem:

char *someproc(void) {
     char test[10];
     strcpy(test, "OogaBooga";
     return test;   /* This is a bad idea */
}

That problem is not unique to C, however, the following RPG code does the
same thing:

     P someproc        B
     D someproc        PI              *
     D test            s             10
     c                   eval      test = 'OogaBooga
      * This is a bad idea:
     c                   return    %addr(test)
     P                 E

> The allocated section of memmory is 'lost' until the job terminates or
> it is expressly FREE'd.  If the code is called multiple times, you start
> to lose memory.  How does RPG get around this?

The difference is...  RPG is able to pass strings by value.  C, on the
other hand, doesn't do that easily.  For example, the following is valid
RPG code:

     P someproc        B
     D someproc        PI            10A
     c                   return    'OogaBooga'
     P                 E

If you wanted to do the same thing in C, you'd have to return a data
structure.  The following C code returns a string by value:

typedef struct dsTest {
   char string[10];
} myTest;

myTest someproc(void) {
    myTest rtn;
    strcpy(rtn.string, "OogaBooga");
    return rtn;
}

The other big difference is that C will null-terminate strings.  In the
examples above, the C code will automatically add a x'00' (err, 0x00
character) after the string "OogaBooga".  The RPG code does not do that.

Yet another issue that you need to be aware of is C's "widening rules."  C
programs will automatically upgrade the sizes of variables for performance
reasons.  You can disable this behavior by specifying "nowiden" on a
#pragma argument or #pragma linkage compiler directive.

> I have applications in both ILE C/400 and RPGLE.  I'm trying to write a
> SRVPGM in RPG that is callable by either language.  (I am more
> comfortable in RPG than C.)  For returning an integer, I can define the
> prototype to be '5I 0' and it works fine.

That's good.


> However, when I try to return a string from RPG to a C program I get an
> MCH3601 - Pointer not set for location referenced.  (It gets the parms
> and does all the work, it fails on the RETURN statement.)  The routine
> works fine for other RPGLE and CLLE programs.  What am I doing wrong?

You wrote the C prototype so that it expects a pointer.  Look again at
this prototype:

> C:   unsigned int *MYFUNCT2(char *);
> (Unsigned Integers are 4 bytes long, same as the 4 char field in RPG.  I
> have a C routine called by RPG that treats them both this same way and
> it works.)

Yes, you're right that unsigned integers are 4 bytes long.   However, this
prototype does not return an unsigned int.   It returns A POINTER TO an
unsigned int.  The equivalent prototype in RPG would be:

     D MYFUNCT2        PR              *
     D   arg                         15A

If your RPG prototype looks like this:

     D MYFUNCT2        PR             4A
     D   arg                         15A

then you need to make your C prototype return it's unsigned int by VALUE:

   unsigned int MYFUNCT2(char *arg);

But, IMHO, it's a poor practice to tell the compiler that the data is
alphanumeric in one place and numeric in another.  Instead, either return
a 4-byte integer in RPG, like this:

     D MYFUNCT2        PR            10U 0
     D   arg                         15A

Or, alternately, make the C program receive a 4-byte character by value:

typedef struct structTest {
   char val[4];
} RetVal;

RetVal MYFUNCT2(char *);

If you do that, make sure that you understand that the 'val' string will
NOT be null-terminated.  Your C code will probably want to memcpy() it to
a "char foo[5]" and set the 5th byte to 0x00 in order to null-terminate
it.

Hope that helps...


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.