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