Peter,

You have two problems:

0007.00 char* getStr(int incomingVar)
0008.00 {
0009.00  char foo[25];
0010.00  sprintf(foo,"%d",incomingVar);
0011.00  return foo;
0012.00 }

"foo" only exists when this function is running. When it ends, the memory is returned to the system. One fix would be to make it static, but even then your code will reuse the same memory each time, making it difficult to use this function in an expression. Not a good way to write code.



0001.00 D getStr          PR            25A   extproc('getStr')
0002.00 D                                5I 0 VALUE
0003.00 C                   MOVEL     *BLANKS       FOOSTR           25
0004.00 C                   Eval      FOOSTR = getStr(1)
0005.00 C                   Eval      *INLR = *ON

The big problem here is that your prototype seems to have no relationship (other than the name) to the C function's prototype. In the C function, you receive a 32-bit integer and return a pointer. In the RPG prototype you pass a 16-bit integer, and return a fixed length 25 character string.

Pointers aren't the same thing as character strings. You can't use them interchangably!

If you want to re-do the C code to match the RPG code, you'd have to do the following:

   typedef struct {
       char data[25];
   } String25;

   String25 getStr(short incomingVar) {
       String25 retval;
       memset(&retval, ' ', sizeof(retval));
       sprintf(retval.data, "%d", incomingVar);
       return String25;
   }

Actually, that's still wrong because it'll put a null character (x'00') after the number in the string. So to do it right, you'd have to find that null-terminator and replace it with a space. Writing fixed length strings in C is not easy.

It would be much easier to fix the RPG prototype instead of changing the C function. More effort has been made to make RPG compatible with C than vice-versa.

Let's look at your C function again:

   char* getStr(int incomingVar)
   {
       static char foo[25];
       sprintf(foo,"%d",incomingVar);
       return foo;
   }

It receives a 32-bit integer, and returns a pointer. Note that I made the "foo" variable static. You can do that easily enough in RPG:

    D getStr          PR              *   extproc('getStr')
    D                               10I 0 VALUE

Note that I changed the parameter to "10I 0" to make it a 32-bit one, and I changed the return value to a pointer. Now it matches the C prototype. Unfortunately, that'll return a pointer to a C-style string, which isn't too useful to the RPG program. Fortunately, RPG provides a BIF called %STR that will convert it for us.

          C                   eval      FOOSTR = %str(getStr(1))
          C                   eval      *inlr = *on

Note that moving blanks to it beforehand is totally unnecessary, since the EVAL statement will set every position of the string, anyway... moving blanks didn't accomplish anything.

I think that this has something to do with the pointer that I'm creating
doesn't exist outside of the service program?  Is this correct, or am I
just making a big goof?

Yes, that's part of it... but the fact that the RPG program is viewing it as a string rather than as a pointer was another problem.

What is the "Right Way" for me to return a char* array (or even a data
structure) via a bound-C service program to a RPG program?  Is there
even a right way to do it?

Just make the definitions match, that's all that's needed.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2019 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].