| 
 | 
Hello,
anybody know how to prototype the following RPG prototype of a export procedure in c?
Yes, I do. :)
D $rtvREFERP pr n D prefCat 3 value D prefKey 27 value D pRefDat 90 options(*nopass :*varSize) D pRefDatLen 2 0 value options(*nopass)
This isn't a very C friendly prototype. Here are a few considerations: a) prefCat & prefKey are alphanumeric strings, but are passed by value.That's a somewhat alien concept in C. You can't usually pass a character string by value, only reference. However, there's an easy workaround... if you put the character string in a data structure, you can pass that data structure by value. It works.
b) The options(*nopass) parameters should be replaced by ... on a C prototype. Unfortunately, that means that the compiler won't check that you're passing the correct parameter type, you'll have to rely on the programmer.
b) The return type of N (an RPG indicator) is a 1-character variable. RPG will pass that as a character string, but C will be looking for a 1 character numeric field. Somewhere under the covers, they're treated differently, and this causes problems.
There are two workarounds. One is to change the RPG prototype to use ExtProc(*CL). Unfortunately, that means you have to recompile all existing programs that call the RPG subprocedure.
The other alternative is to return a 2-character long data structure in the C program, and then just ignore the 2nd character. This'll cause C to set up the return type the way the RPG program would.
Note that you'd have this same problem if you called the RPG from a CL porgram. That's why the fix is called ExtProc(*CL) from within RPG. In my prototype, however, I'll use the C workaround isntead of changing the RPG because it's less intrusive.
c) In order for %PARMS to work in the RPG subprocedure, you need to pass at least a minimal operational descriptor. RPG does this automatically, as does CL. But in C to make it do that, you have to force the issue with a descriptor #pragma.
d) Unless you use ExtProc, an RPG program converts the subprocedure's name to all-uppercase. C, on the other hand, keeps things in the same case that you typed. So to use the name "$rtvREFERP" in the C program, you need to use a map #pragma to rename it. (#pragma map is like ExtPRoc in RPG)
Taking all of these things into account, here's the prototype that I came up with:
#include <decimal.h>
typedef struct {
   char value[3];
} prefCat_t;
typedef struct {
   char value[27];
} prefKey_t;
typedef struct {
   char value;
   char reserved;
} prefRtn_t;
#pragma map ($rtvREFERP, "$RTVREFERP")
prefRtn_t $rtvREFERP( prefCat_t prefCat, prefKey_t prefKey, ...);
#pragma descriptor ( void $rtvREFERP(void,void) )
Here's an example of calling the subprocedure from ILE C, with and without 
the optional parms:
#include <stdio.h>
#include <string.h>
#include "QCSRC/RTVREFERP"
int main(int argc, char **argv) {
#define DATALEN 90
    prefCat_t cat;
    prefKey_t key;
    prefRtn_t rc;
    char data[DATALEN+1];
    _Decimal(2,0) len;
    /* RPG doesn't like null-terminated strings.  The data for
       each argument goes at the start of the variable, and the
       rest of the variable should be filled with blanks. */
    memset(&cat, ' ', sizeof(key));
    memset(&key, ' ', sizeof(key));
    memcpy(&cat, "AA", 2);
    memcpy(&key, "Whatever goes in prefKey...", 27);
    /* Call RPG subprocedure */
    rc = $rtvREFERP( cat, key );
    printf("rc = %c\n", rc.value);
    /* Call again with optional parms supplied */
    len = DATALEN;
    memset(data, ' ', DATALEN);
    memcpy(data, "Some sort of data", 17);
    rc = $rtvREFERP( cat, key, data, len );
    data[DATALEN] = '\0';
    printf("rc = %c, data = %s \n", rc.value, data);
    return 0;
}
Hope that helps...
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 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.