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



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

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

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.