|
Wow! -----Original Message----- From: c400-l-bounces+lim.hock-chai=usamobility.com@xxxxxxxxxxxx [mailto:c400-l-bounces+lim.hock-chai=usamobility.com@xxxxxxxxxxxx] On Behalf Of Scott Klement Sent: Wednesday, November 16, 2005 3:57 PM To: C programming iSeries / AS400 Subject: Re: [C400-L] prototype in c 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... -- This is the C programming iSeries / AS400 (C400-L) mailing list To post a message email: C400-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options, visit: http://lists.midrange.com/mailman/listinfo/c400-l or email: C400-L-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/c400-l.
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.