ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Calling ICU APIs from RPG

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Calling ICU APIs from RPG

    Hello *ALL,

    I'm trying to call an ICU APIs from RPG but can't get it running and i think its due to parameter mismatch.
    https://unicode-org.github.io/icu-do.../uidna_8h.html - API "uidna_IDNToASCII()"


    My code looks like following:

    Code:
    **free
    Ctl-Opt BndDir('QICU/QXICUAPIBD');
    
    //************************************************** **
    // Prototypes *
    //************************************************** **
    Dcl-Pr StrToPunycode Int(10) ExtProc('uidna_IDNToASCII_4_0');
      Src Uns(5) Value;
      SrcLen Int(10);
      Dest Uns(5) Value;
      DestCapacity Int(10);
      Options Int(10);
      ParseError LikeDs(ParseError);
      ErrorCode Int(10);
    End-Pr;
    
    //************************************************** **
    // Variables *
    //************************************************** **
    Dcl-Ds Src Qualified;
      Dec Uns(5) Inz(0);
      Value UCS2(64) Pos(1);
    End-Ds;
    
    Dcl-Ds Dest Qualified;
      Value UCS2(64) Inz('');
      Dec Uns(5);
    End-Ds;
    
    Dcl-S DestCapacity Int(10);
    Dcl-S Options Int(10);
    Dcl-S ErrorCode Int(10);
    Dcl-S Len Int(10);
    Dcl-S SrcLen Int(10);
    
    Dcl-Ds ParseError Qualified;
      Line Int(10);
      Offset Int(10);
      Dcl-Ds PreContext;
        Value UCS2(32) Inz('');
        Dec Uns(5) Pos(1);
      End-Ds;
      Dcl-Ds PostContext;
        Value UCS2(32) Inz('');
        Dec Uns(5) Pos(1);
      End-Ds;
    End-Ds;
    
    //************************************************** **
    // Main *
    //************************************************** **
    Src.Value = 'HALLÖ.COM';
    SrcLen = %Len(Src.Value);
    DestCapacity = %Size(Dest.Value);
    Options = *Zero;
    
    Len = StrToPunycode(Src.Dec :
                         SrcLen :
                       Dest.Dec :
                   DestCapacity :
                        Options :
                     ParseError :
                     ErrorCode) ;
    
    *INLR = *On;
    I think i got the Int(10) Parameters right but the UCHAR (Src, Dest, ParseError) Parameters seem wrong. Does anyone know how to define the UCHAR Parameters in RPG.

    Thanks in advance
    Luca Altmann

  • #2
    Hi Luca, finally we can reply to your post.

    When a C definition has an asterisk (UChar *src), it means either "pointer to one UChar" or "array of UChar passed by reference". In this case, since you also provide a length for this parameter, it is an array of UChar.

    In RPG, it might be an array of unsigned integer
    Code:
    Uns(5) DIM(SOME_LENGTH)
    or it might be a UCS-2 string
    Code:
    Ucs2(SOME_LENGTH)
    But since the function is about a conversion to ASCII, I think it is a UCS-2 string.

    Comment


    • #3
      For the benefit of those who read this thread in the future. I have been communicating with Luca and the following is a version of his code with a modified prototype etc. that works.

      Note that the source and destination fields are defined as only 20 long simply to allow me to use DSPLY to see the results. They should obviously be much longer in real life. Luca tells me that this version is working for him. So here's the code.
      Code:
      **free
      
      Ctl-Opt BndDir('QICU/QXICUAPIBD');
      
      //************************************************** **
      // Prototypes *
      //************************************************** **
      
      Dcl-Pr StrToPunycode Int(10) ExtProc('uidna_IDNToASCII_4_0');
         Src           UCS2(20); // Or Pointer passed by value with address of data
         SrcLen        Int(10) Value;
         Dest          UCS2(20);
         DestCapacity  Int(10) Value;
         Options       Int(10)  Value;
         ParseError    LikeDs(ParseError);
         ErrorCode     Int(10);
      End-Pr;
      
      //************************************************** **
      // Variables *
      //************************************************** **
      
      Dcl-s  Src UCS2(20) Inz('HALLÖ.com');
      Dcl-s  Dest UCS2(20);
      
      dcl-ds TestSize  Inz;
         TestUSC2  UCS2(20);
      End-Ds;
      
      Dcl-S DestCapacity  Int(10);
      Dcl-S Options       Int(10);
      Dcl-S ErrorCode     Int(10);
      Dcl-S Len           Int(10);
      Dcl-S SrcLen        Int(10);
      
      Dcl-Ds ParseError Qualified Inz;
         Line         Int(10);
         Offset       Int(10);
         PreContext   UCS2(16);
         PostContext  UCS2(16);
      End-Ds;
      
      //************************************************** **
      // Main *
      //************************************************** **
      
      SrcLen = %Len(%Trim(Src));
      
      DestCapacity = %Size(Dest);
      
      Options = 0;
      
      Len = StrToPunycode(Src :
                           SrcLen :
                             Dest :
                     DestCapacity :
                          Options :
                       ParseError :
                       ErrorCode) ;
      
      If ParseError.Line <> 0;
         Dsply ( 'Error on line ' + %Char(ParseError.Line) );
      Else;
         Dsply ( 'Returned count = ' + %Char(Len) );
         Dsply %Subst( Dest: 1: Len);
      EndIf;
      
      *INLR = *On;

      Comment


      • #4
        Thanks a lot Barbara and Jon for your help!

        Comment

        Working...
        X