Float type parameter containing incorrect value after a callp

45 pts.
Tags:
float parameter
Parameters
PGM
RPG
V5R4
I'm calling a procedure from an rpg pgm(V5R4). It has several parameters with different types. Before calling, they are set to 0 or blanks. After calling, all is coming back with correct value except for 1 float(8f) field. We don't have the source for the procedure however, it's been tested in C pgm and it works fine. See definition below. First 3 parms are for input and the rest are output fields. Tax has the issue. Please advise. Thank you.

d GetLn   pr              n   ExtProc('GetLn')   d   Hdl                        *   Value                        d   LineItem#                10i 0 Value                        d   Type                        10i 0 Value                        d   TaxFlag                    10i 0                              d   TaxType                   10i 0                              d   TaxIncF                    10i 0                              d   ExReasCd                 1A                                d   ExAmt                       8f                                d   NTxReasCd               1A                                d   NTxAmt                     8f                                d   Rate                         8f                                d   RAteEffDt                   8A                                d   TaxedAmt                  8f                                d   Tax                           8f                                d   DiAppFlag                 10i 0  value                      

Answer Wiki

Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Discuss This Question: 10  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • TomLiotta
    First 3 parms are for input and the rest are output fields. I'm pretty sure that at least one of the rest of the parms is not an output parm:
    d   DiAppFlag           10i 0  value
    If the 'GetLn' proc is trying to output a value into DiAppFlag, I'd expect 'unpredictable results'. With seeing how 'GetLn' defines and uses its arguments, there's not much chance of knowing what might happen. Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    This is the prototype. We don't see the acutal definitions of the fields, or the Call. We have to accept the prototype but we might see an error on the others. Be sure to use the Code button to start/end your code. Phil
    49,730 pointsBadges:
    report
  • kglen01
    ***  This is the definition of the function supplied to us. 
    ***  Only the first 3 parms are definitely for input. 
    ***  The rest of the parameters are for output and may be ignored if NULL is passed
    typedef BOOL (POSTFIX *tGetLn) (Hdl pDataHdl,      
              long pInvLineItemNo,                               
              int   pLocType,                          
              int *pLocTaxbltyFlag,                    
              int *pLocTaxType,                        
              int *pLocTaxInclFlag,                    
              char *pLocExmtReasCd,                            
              double *pLocExmtAmt,                             
              char *pLocNonTaxReasCd,                          
              double *pLocNonTaxAmt,                           
              double *pLocRate,                                
              char *pLocRateEffDate,                           
              double *pLocTaxedAmt,                            
              double *pLocTax,                                 
              int *pLocDiApplFlag);                              
    
    *** In RPG pgm, Hdl=Handle, pInvLineItem#=1 and Type =0 are passed to the function. c                   eval      lbool    = GetLn(                
    c                                       hdl:                       
    c                                       LineItem#:                 
    c                                       Type:                       
    c                                       TaxFlag:                    
    c                                       TaxType:                    
    c                                       TaxIncF:                    
    c                                       ExReasCd:                   
    c                                       ExAmt:                      
    c                                       NTxReasCd:                  
    c                                       NTxAmt:                     
    c                                       Rate:                       
    c                                       RAteEffDt:                  
    c                                       TaxdAmt:                    
    c                                       Tax:                        
    c                                       DiAppFlag)                  
    
    Ex of Tax Value result Before calling the function : 0.000000000000E+000 After calling the function: 3.259733202713E-308 Expected result is 5.860000000000000E+000 I tested the pgm without the "value" keyword for DiAppFlag but same incorrect result in tax field. I tried omitting all other output parameters that's not needed but same incorrect result in tax field. Thanks for the feedbacks.
    45 pointsBadges:
    report
  • TomLiotta
    Try changing this line:
    d GetLn   pr              n   ExtProc('GetLn') 
    ...to this:
    d GetLn   pr              n   ExtProc(*CWIDEN : 'GetLn') 
    I don't know how GetLn was compiled, so there is guesswork involved. But you have three 1A parms that can be causing problems. Passing parms to C can require some understanding of C's parameter-passing protocols. By asking the RPG compiler to apply C widening for appropriate parms, those three 1A parms might be handled better. Because they are 'output' parms, they might affect values in other variables. Make sure that you leave the VALUE keyword off of DiAppFlag. Let us know of any changes in your return values. Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    Don't think this is an issue char *pLocRateEffDate, is char but you've mapping an 8 alpha to it. Phil
    49,730 pointsBadges:
    report
  • TomLiotta
    d   RAteEffDt                   8A
    It's 8-characters in the prototype from what I see. C widening might not be the exact problem here, but it's definitely "a" significant potential problem that needs to be fixed. Until we see how the called proc handles a correct parameter list, we'll be guessing. A 1A parameter is going to be handled as a 4-byte integer in a C parameter list. When C tries to return a value, there will be potentially three bytes of memory in the calling program that can be corrupted. (Unless the C is compiled under a #pragma that causes a non-standard behavior. But that doesn't seem likely after looking at the C prototype.) At the moment, we don't know what the correct prototype in RPG should be. Tom
    125,585 pointsBadges:
    report
  • kglen01
    The *CWIDEN did not correct the issue. Thanks for pointing me to the char issue. I'm not at all familiar with C. Tried reaching out to the vendor if I'm missing anything. I corrected the 1A field definition to be 5A I tried omitting the 3 char fields and it worked. Although, this is working, I'm afraid this does not totally fix the issue and it might cause unpredictable results. Any thoughts about issues on ignoring the parameters? (I put CONST *OMIT on all 3 parms then pass *OMIT in callp) fyi When compiling the RPG program, we just needed to bind it with the vendor service program. Thanks again . I appreciate the help.
    45 pointsBadges:
    report
  • TomLiotta
    Any thoughts about issues on ignoring the parameters? My only thought comes from this comment with the C prototype:
    • The rest of the parameters are for output and may be ignored if NULL is passed
    It seems valid to *OMIT them. But there's no definition of what that means, and the reasonable expectation is that your RPG program doesn't require the returned values. In that case, you probably should *OMIT them anyway. I'd probably have the RPG prototype specifying *OMIT for all of the output parms since it (apparently) matches what C expects. I corrected the 1A field definition to be 5A If you aren't sure of a char * length for an output parm, it is necessary to know the maximum length that may be returned. Your RPG prototype might need to specify the maximum size and include OPTIONS(*VARSIZE) for that parm for cases where you might use variables of different sizes in different CALLP statements or different RPG programs. That allows the compiler to ensure that enough memory is made available for C to return the maximum length without clobbering something else -- even if you pass in a variable that is shorter than the maximum. If the 1A parms really weren't 1A, they needed to be corrected. The appropriate sizes are always needed. If 5A is correct, then widening (probably) isn't needed. Note that maximum size and OPTIONS(*VARSIZE) should take care of that. If 5-bytes is the maximum, then 5A is appropriate. Note that OPTIONS(*VARSIZE) is not at all the same as VARYING which indicates a variable-length field. Only a couple more bits -- Are any of the values null-terminated? And is hdl a pointer? (It seems to be.) Null-terminated strings may need OPTIONS(*STRING), and if hdl is not a pointer, then the CALLP should perhaps have %ADDR(hdl). Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    I'm confused, again, as usual, isn't the char type is C one byte, but nothing on the 400 is one byte...... Phil
    49,730 pointsBadges:
    report
  • TomLiotta
    isn’t the char type is C one byte Yes and no. The trouble is that it's not a "char" -- it's a "char *". That's combined with the lack of an actual "string" data type in C. And it's an output value. If it was just input, a C programmer might ask for a "char" rather than "char *". The "char" could be supplied 'by value' rather than 'by reference'. We'd be more certain what was wanted. We can't know if the C proc is looking for a simple "char" or an array of chars or a null-terminated string; at least, we don't know from what we've seen so far. Those three variants will all be possible from a "char *" declaration. It'd be a lot easier if we could chat with the C programmer. So, we do some guessing. Tom
    125,585 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following