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



Perhaps you omitted code in your C routine I don't see where you're
accessing the *str input parameter.
Anyway, in RPG IV if you use OPTIIONS(*STRING) and VALUE for a parm, you
don't also then use %ADDR(someVar) when you pass a value to that parameter.
You simply code as is. In other words:
This...
Pr_ChkDigit(%Addr(Wrk_Str));
Should be this...

Pr_ChkDigit(Wrk_Str);

And you don't need to add the NULL since OPTIONS(*STRING) does that for you.

-Bob Cozzi
www.RPGxTools.com
If everything is under control, you are going too slow.
- Mario Andretti


-----Original Message-----
From: c400-l-bounces+cozzi=rpgiv.com@xxxxxxxxxxxx
[mailto:c400-l-bounces+cozzi=rpgiv.com@xxxxxxxxxxxx] On Behalf Of
c400-l-request@xxxxxxxxxxxx
Sent: Wednesday, April 20, 2005 4:38 PM
To: c400-l@xxxxxxxxxxxx
Subject: C400-L Digest, Vol 3, Issue 42

Send C400-L mailing list submissions to
        c400-l@xxxxxxxxxxxx

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.midrange.com/mailman/listinfo/c400-l
or, via email, send a message with subject or body 'help' to
        c400-l-request@xxxxxxxxxxxx

You can reach the person managing the list at
        c400-l-owner@xxxxxxxxxxxx

When replying, please edit your Subject line so it is more specific
than "Re: Contents of C400-L digest..."


Today's Topics:

   1. Returning character variables from C to RPG (Krish Thirumalai)
   2. RE: Returning character variables from C to RPG (Elvis Budimlic)
   3. Re: Returning character variables from C to RPG (Krish Thirumalai)
   4. Re: Returning character variables from C to RPG (Scott Klement)
   5. Re: Returning character variables from C to RPG (Scott Klement)
   6. Re: Returning character variables from C to RPG (Krish Thirumalai)


----------------------------------------------------------------------

message: 1
date: Wed, 20 Apr 2005 16:42:22 -0400
from: Krish Thirumalai <krishnithya@xxxxxxxxx>
subject: [C400-L] Returning character variables from C to RPG

Writing my first program in C in the ILE environment and I am really 
puzzled.

I have the following RPG program that is calling a C function, but all i get

back is a Null each time. If i put it in debug mode i can see that the value

of chkdigit is correct, but then, when i get it back in my RPG, the value is

NULL.

Can someone point out what i am doing wrong ?

RPG program

D Pr_ChkDigit PR * ExtProc('Pr_ChkDigit') 
D * Options(*string) value 

D Wrk_Str s 36A 
D Wrk_Null s 1A Inz(X'00') 
D Wrk_ChkDigit s 1A 
D Ptr_ChkDigit s * INZ(%ADDR(Wrk_ChkDigit)) 

/Free 
Wrk_Str = '70500607050AEI02x' + Wrk_Null; 
Ptr_ChkDigit = Pr_ChkDigit(%Addr(Wrk_Str)); 
Dsply Wrk_ChkDigit; 
*InLr = *on; 
/End-Free 

C service program

// Mod 36 Check bit calculator 
char* Pr_ChkDigit(char *str) 
{ 

char chkdigit; 
char* check_bit; 

//Calcuations 
// Get checkbit from the Mapping Matrix 
chkdigit=reverse_map(c1,c2) ; 
*check_bit = chkdigit; 
return check_bit; 

} 



-- 
Krish Thirumalai


------------------------------

message: 2
date: Wed, 20 Apr 2005 15:50:39 -0500
from: "Elvis Budimlic" <ebudimlic@xxxxxxxxxxxxxxxxxxxxxxxxx>
subject: RE: [C400-L] Returning character variables from C to RPG

What if you use:

// Mod 36 Check bit calculator 
char* Pr_ChkDigit(char *str) 
{ 

char chkdigit; 

//Calcuations 
// Get checkbit from the Mapping Matrix 
chkdigit=reverse_map(c1,c2) ; 
*str = chkdigit; 
return str; 

}

-----Original Message-----
From: c400-l-bounces+ebudimlic=centerfieldtechnology.com@xxxxxxxxxxxx
[mailto:c400-l-bounces+ebudimlic=centerfieldtechnology.com@xxxxxxxxxxxx] On
Behalf Of Krish Thirumalai
Sent: Wednesday, April 20, 2005 3:42 PM
To: c400-l@xxxxxxxxxxxx
Subject: [C400-L] Returning character variables from C to RPG

Writing my first program in C in the ILE environment and I am really 
puzzled.

I have the following RPG program that is calling a C function, but all i get

back is a Null each time. If i put it in debug mode i can see that the value

of chkdigit is correct, but then, when i get it back in my RPG, the value is

NULL.

Can someone point out what i am doing wrong ?

RPG program

D Pr_ChkDigit PR * ExtProc('Pr_ChkDigit') 
D * Options(*string) value 

D Wrk_Str s 36A 
D Wrk_Null s 1A Inz(X'00') 
D Wrk_ChkDigit s 1A 
D Ptr_ChkDigit s * INZ(%ADDR(Wrk_ChkDigit)) 

/Free 
Wrk_Str = '70500607050AEI02x' + Wrk_Null; 
Ptr_ChkDigit = Pr_ChkDigit(%Addr(Wrk_Str)); 
Dsply Wrk_ChkDigit; 
*InLr = *on; 
/End-Free 

C service program

// Mod 36 Check bit calculator 
char* Pr_ChkDigit(char *str) 
{ 

char chkdigit; 
char* check_bit; 

//Calcuations 
// Get checkbit from the Mapping Matrix 
chkdigit=reverse_map(c1,c2) ; 
*check_bit = chkdigit; 
return check_bit; 

} 



-- 
Krish Thirumalai
_______________________________________________
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.







------------------------------

message: 3
date: Wed, 20 Apr 2005 17:08:09 -0400
from: Krish Thirumalai <krishnithya@xxxxxxxxx>
subject: Re: [C400-L] Returning character variables from C to RPG

That did return the pointer back, but the original string was modified. 

String sent
'70500607050AEI02x' 

String returned
'J0500607050AEI02x' 

I was expecting to get just the value J which is the check digit that got 
generated.

On 4/20/05, Elvis Budimlic <ebudimlic@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> 
> What if you use:
> 
> // Mod 36 Check bit calculator
> char* Pr_ChkDigit(char *str)
> {
> 
> char chkdigit;
> 
> //Calcuations
> // Get checkbit from the Mapping Matrix
> chkdigit=reverse_map(c1,c2) ;
> *str = chkdigit;
> return str;
> 
> }
> 
> -----Original Message-----
> From: c400-l-bounces+ebudimlic=centerfieldtechnology.com@xxxxxxxxxxxx
> [mailto:c400-l-bounces+ebudimlic=centerfieldtechnology.com@xxxxxxxxxxxx] 
> On
> Behalf Of Krish Thirumalai
> Sent: Wednesday, April 20, 2005 3:42 PM
> To: c400-l@xxxxxxxxxxxx
> Subject: [C400-L] Returning character variables from C to RPG
> 
> Writing my first program in C in the ILE environment and I am really
> puzzled.
> 
> I have the following RPG program that is calling a C function, but all i 
> get
> 
> back is a Null each time. If i put it in debug mode i can see that the 
> value
> 
> of chkdigit is correct, but then, when i get it back in my RPG, the value 
> is
> 
> NULL.
> 
> Can someone point out what i am doing wrong ?
> 
> RPG program
> 
> D Pr_ChkDigit PR * ExtProc('Pr_ChkDigit')
> D * Options(*string) value
> 
> D Wrk_Str s 36A
> D Wrk_Null s 1A Inz(X'00')
> D Wrk_ChkDigit s 1A
> D Ptr_ChkDigit s * INZ(%ADDR(Wrk_ChkDigit))
> 
> /Free
> Wrk_Str = '70500607050AEI02x' + Wrk_Null;
> Ptr_ChkDigit = Pr_ChkDigit(%Addr(Wrk_Str));
> Dsply Wrk_ChkDigit;
> *InLr = *on;
> /End-Free
> 
> C service program
> 
> // Mod 36 Check bit calculator
> char* Pr_ChkDigit(char *str)
> {
> 
> char chkdigit;
> char* check_bit;
> 
> //Calcuations
> // Get checkbit from the Mapping Matrix
> chkdigit=reverse_map(c1,c2) ;
> *check_bit = chkdigit;
> return check_bit;
> 
> }
> 
> --
> Krish Thirumalai
> _______________________________________________
> 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.
> 
> _______________________________________________
> 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.
> 
> 


-- 
Krish Thirumalai


------------------------------

message: 4
date: Wed, 20 Apr 2005 16:17:34 -0500 (CDT)
from: Scott Klement <c400-l@xxxxxxxxxxxxxxxx>
subject: Re: [C400-L] Returning character variables from C to RPG

Hello,

> I have the following RPG program that is calling a C function, but all i
get
> back is a Null each time. If i put it in debug mode i can see that the
value
> of chkdigit is correct, but then, when i get it back in my RPG, the value
is
> NULL.

In your code, you declare two variables that are local to the function. A 
one character variable called "chkdigit" and a pointer to a character 
called "check_bit"

> char* Pr_ChkDigit(char *str)
> {
>
> char chkdigit;
> char* check_bit;

At the time that these start up, what are they set to?  Nothing in 
particular. C doesn't initialize variables, so they could really have any 
value.

Most of the time, they'll probably be 0x00, but you can't be sure.  That 
also means that the pointer will be NULL, since a pointer that's set to 
all zeroes is NULL.

Now look at the code that uses them:

> //Calcuations
> // Get checkbit from the Mapping Matrix
> chkdigit=reverse_map(c1,c2) ;

Okay, this changes the value of chkdigit.

> *check_bit = chkdigit;

Now, this copies the value of chkdigit to whatever memory is stored where 
"check_bit" points to.  Where does check_bit point to?   Most of the time, 
it'll be NULL.  Sometimes it might actually point to real memory, in which 
case you've just corrupted that memory, because you haven't allocated 
anything to it!

> return check_bit;

And now you're returning the pointer, which will usually be NULL.

It might be tempting to return &chkdigit instead. (The address of the 
chkdigit variable) but that would also be wrong, since this is the last 
statement of your function, and the memory that was allocated to the 
chkdigit variable will be deallocated before control is returned to the 
caller.

IMHO, it would make more sense to return a character than to return a 
pointer!  That way, you won't have to worry about the memory being freed 
up.

If you DO want to work with a pointer for some reason, I strongly 
recommend passing that pointer in as a parameter so that it refers to the 
caller's storage instead of the something allocated by the function 
itself.  That way, you don't have to worry about when it gets allocated or 
deallocated. Make that the caller's responsibility -- it gives the caller 
the option of using automatic storage or static storage or whatever they 
want to use.

Now let's talk about your RPG program :)

> D Pr_ChkDigit PR * ExtProc('Pr_ChkDigit')
> D * Options(*string) value
>
> D Wrk_Str s 36A
> D Wrk_Null s 1A Inz(X'00')
> D Wrk_ChkDigit s 1A
> D Ptr_ChkDigit s * INZ(%ADDR(Wrk_ChkDigit))
>
> /Free
> Wrk_Str = '70500607050AEI02x' + Wrk_Null;
> Ptr_ChkDigit = Pr_ChkDigit(%Addr(Wrk_Str));
> Dsply Wrk_ChkDigit;
> *InLr = *on;
> /End-Free

(Wow, is that hard to read. What happened to the spaces that put things 
into the right columns?)

The options(*string) on the prototype says to the compiler "I want you to 
automatically add a x'00' to the end of the string when you pass it." 
Then, what's the very first thing you do in your code?  You manually add a 
x'00'. You don't need to do that! You just told the compiler to do it for 
you!!

In the next line of code, you call the PR_ChkDigit() function and you tell 
it to assign the result to your pointer called Ptr_ChkDigit.  Okay, so why 
did you assign the address of Wrk_ChkDigit to the pointer in the D-specs, 
if the very first thing in your program is to change that value to 
something else?!

Not only that, but the DSPLY that occurs on the next line won't do you any 
good because Wrk_ChkDigit no longer has any relationship to Ptr_ChkDigit. 
It doesn't make any sense!

You probably intended to do the following:

      D Ptr_ChkDigit    s               *
      D Wrk_ChkDigit    s              1A   based(Ptr_ChkDigit)

There's a BIG difference. When you initialize a pointer to the address of 
a field, RPG allocates memory for that field, and then sets the pointer to 
the address of the memory it allocated.

When you use BASED, you say "this field is always located in the memory 
that I point to with the basing pointer".  RPG won't allocate any memory 
to the field, because you can change where the field points to, so 
allocating memory wouldn't make sense.

Basically, BASED is like dereferencing a pointer in C. In other words, 
these two sets of code do the same thing:

      D Ptr_ChkDigit    s               *
      D Wrk_ChkDigit    s              1A   based(Ptr_ChkDigit)

        Ptr_ChkDigit = %alloc(1);
        Wrk_ChkDigit = something;
        dealloc Ptr_ChkDigit;

is the same as:

      char *ptr_chkdigit;
      ptr_chkdigit = malloc(1);
      *ptr_chkdigit = something;
      free(ptr_chkdigit);

And the following two code snippets are likewise the same:

      D Ptr_ChkDigit    s               *    inz(%addr(WrkChkDigit))
      D Wrk_ChkDigit    s              1A

        Wrk_ChkDigit = something;

is the same as:

      char wrk_chkdigit;
      char *ptr_chkdigit;

      ptr_chkdigit = &wrk_chkdigit;
      wrk_chkdigit = something;

Does that help?


------------------------------

message: 5
date: Wed, 20 Apr 2005 16:29:51 -0500 (CDT)
from: Scott Klement <c400-l@xxxxxxxxxxxxxxxx>
subject: Re: [C400-L] Returning character variables from C to RPG

Hello,

On Wed, 20 Apr 2005, Scott Klement wrote:
>
> IMHO, it would make more sense to return a character than to return a 
> pointer!  That way, you won't have to worry about the memory being freed
up.
>

Reading back my message, I don't think I made it very clear what I 
recommended.  I recommend the following as the solution to your problem:

      D Pr_ChkDigit     PR             1A   ExtProc(*CWIDEN: 'Pr_ChkDigit')
      D   str                           *   value options(*string)

      D Wrk_Str         s             36A
      D Wrk_ChkDigit    s              1A

       /free
           Wrk_ChkDigit = Pr_ChkDigit('70500607050AEI02x');
           dsply Wrk_ChkDigit;
           *inlr = *on;
       /end-free

Or, if you prefer to put the number into a variable:

       /free
           Wrk_Str = '70500607050AEI02x';
           Wrk_ChkDigit = Pr_ChkDigit(%trimr(WrkStr));
           dsply Wrk_ChkDigit;
           *inlr = *on;
       /end-free

And the C function should look like this:

   char Pr_ChkDigit(const char *str)
   {
      char chkdigit;
      chkdigit = reverse_map(c1,c2);
      return chkdigit;
   }

Actually, there doesn't seem to be any point to using a variable for the 
check digit. You could just do this:

   char Pr_ChkDigit(const char *str)
   {
      return reverse_map(c1,c2);
   }

Anyway, hope that helps.



------------------------------

message: 6
date: Wed, 20 Apr 2005 17:37:36 -0400
from: Krish Thirumalai <krishnithya@xxxxxxxxx>
subject: Re: [C400-L] Returning character variables from C to RPG

Thanks Scott, 

It does make more sense. I did not really want to use pointers, and i 
realize all the mistakes that i made. 

I originally had the C function just returning the character, and i had it 
defined as follows, but my RPG was not getting back the chkdigit that i was 
returning. Do i have to do something different in my C to return the 
character string ?

char Pr_ChkDigit(char* str) 
{ 
char chkdigit; 
//Calculations
chkdigit=reverse_map(c1,c2) ; 
return chkdigit; 
}

D Pr_ChkDigit PR 1A ExtProc('Pr_ChkDigit')
D * value 

D Wrk_Str s 36A 
D Wrk_Null s 1A Inz(X'00') 
D Wrk_ChkDigit s 1A 

/Free 
Wrk_Str = '70500607050AEI02x' + Wrk_Null; 
Wrk_ChkDigit = Pr_ChkDigit(%Addr(Wrk_Str)); 
Dsply Wrk_ChkDigit; 




On 4/20/05, Scott Klement <c400-l@xxxxxxxxxxxxxxxx> wrote:
> 
> Hello,
> 
> > I have the following RPG program that is calling a C function, but all i

> get
> > back is a Null each time. If i put it in debug mode i can see that the 
> value
> > of chkdigit is correct, but then, when i get it back in my RPG, the 
> value is
> > NULL.
> 
> In your code, you declare two variables that are local to the function. A
> one character variable called "chkdigit" and a pointer to a character
> called "check_bit"
> 
> > char* Pr_ChkDigit(char *str)
> > {
> >
> > char chkdigit;
> > char* check_bit;
> 
> At the time that these start up, what are they set to? Nothing in
> particular. C doesn't initialize variables, so they could really have any
> value.
> 
> Most of the time, they'll probably be 0x00, but you can't be sure. That
> also means that the pointer will be NULL, since a pointer that's set to
> all zeroes is NULL.
> 
> Now look at the code that uses them:
> 
> > //Calcuations
> > // Get checkbit from the Mapping Matrix
> > chkdigit=reverse_map(c1,c2) ;
> 
> Okay, this changes the value of chkdigit.
> 
> > *check_bit = chkdigit;
> 
> Now, this copies the value of chkdigit to whatever memory is stored where
> "check_bit" points to. Where does check_bit point to? Most of the time,
> it'll be NULL. Sometimes it might actually point to real memory, in which
> case you've just corrupted that memory, because you haven't allocated
> anything to it!
> 
> > return check_bit;
> 
> And now you're returning the pointer, which will usually be NULL.
> 
> It might be tempting to return &chkdigit instead. (The address of the
> chkdigit variable) but that would also be wrong, since this is the last
> statement of your function, and the memory that was allocated to the
> chkdigit variable will be deallocated before control is returned to the
> caller.
> 
> IMHO, it would make more sense to return a character than to return a
> pointer! That way, you won't have to worry about the memory being freed
> up.
> 
> If you DO want to work with a pointer for some reason, I strongly
> recommend passing that pointer in as a parameter so that it refers to the
> caller's storage instead of the something allocated by the function
> itself. That way, you don't have to worry about when it gets allocated or
> deallocated. Make that the caller's responsibility -- it gives the caller
> the option of using automatic storage or static storage or whatever they
> want to use.
> 
> Now let's talk about your RPG program :)
> 
> > D Pr_ChkDigit PR * ExtProc('Pr_ChkDigit')
> > D * Options(*string) value
> >
> > D Wrk_Str s 36A
> > D Wrk_Null s 1A Inz(X'00')
> > D Wrk_ChkDigit s 1A
> > D Ptr_ChkDigit s * INZ(%ADDR(Wrk_ChkDigit))
> >
> > /Free
> > Wrk_Str = '70500607050AEI02x' + Wrk_Null;
> > Ptr_ChkDigit = Pr_ChkDigit(%Addr(Wrk_Str));
> > Dsply Wrk_ChkDigit;
> > *InLr = *on;
> > /End-Free
> 
> (Wow, is that hard to read. What happened to the spaces that put things
> into the right columns?)
> 
> The options(*string) on the prototype says to the compiler "I want you to
> automatically add a x'00' to the end of the string when you pass it."
> Then, what's the very first thing you do in your code? You manually add a
> x'00'. You don't need to do that! You just told the compiler to do it for
> you!!
> 
> In the next line of code, you call the PR_ChkDigit() function and you tell
> it to assign the result to your pointer called Ptr_ChkDigit. Okay, so why
> did you assign the address of Wrk_ChkDigit to the pointer in the D-specs,
> if the very first thing in your program is to change that value to
> something else?!
> 
> Not only that, but the DSPLY that occurs on the next line won't do you any
> good because Wrk_ChkDigit no longer has any relationship to Ptr_ChkDigit.
> It doesn't make any sense!
> 
> You probably intended to do the following:
> 
> D Ptr_ChkDigit s *
> D Wrk_ChkDigit s 1A based(Ptr_ChkDigit)
> 
> There's a BIG difference. When you initialize a pointer to the address of
> a field, RPG allocates memory for that field, and then sets the pointer to
> the address of the memory it allocated.
> 
> When you use BASED, you say "this field is always located in the memory
> that I point to with the basing pointer". RPG won't allocate any memory
> to the field, because you can change where the field points to, so
> allocating memory wouldn't make sense.
> 
> Basically, BASED is like dereferencing a pointer in C. In other words,
> these two sets of code do the same thing:
> 
> D Ptr_ChkDigit s *
> D Wrk_ChkDigit s 1A based(Ptr_ChkDigit)
> 
> Ptr_ChkDigit = %alloc(1);
> Wrk_ChkDigit = something;
> dealloc Ptr_ChkDigit;
> 
> is the same as:
> 
> char *ptr_chkdigit;
> ptr_chkdigit = malloc(1);
> *ptr_chkdigit = something;
> free(ptr_chkdigit);
> 
> And the following two code snippets are likewise the same:
> 
> D Ptr_ChkDigit s * inz(%addr(WrkChkDigit))
> D Wrk_ChkDigit s 1A
> 
> Wrk_ChkDigit = something;
> 
> is the same as:
> 
> char wrk_chkdigit;
> char *ptr_chkdigit;
> 
> ptr_chkdigit = &wrk_chkdigit;
> wrk_chkdigit = something;
> 
> Does that help?
> _______________________________________________
> 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.
> 
> 


-- 
Krish Thirumalai


------------------------------

_______________________________________________
This is the C programming iSeries / AS400 (C400-L) digest 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.



End of C400-L Digest, Vol 3, Issue 42
*************************************




As an Amazon Associate we earn from qualifying purchases.

This thread ...


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.