jvalue 構造でのオブジェクト参照の設定

jvalue 構造は次のようになります。

           D jvalue          DS                  QUALIFIED        
           D                                     BASED(jvalue_P)  
            ... more subfields ...
           D   l                                 LIKE(jint)       
           D                                     OVERLAY(jvalue:1)

jvalue 構造の「l」フィールドはオブジェクト参照を表しますが、 RPG はオブジェクト・タイプのサブフィールドをサポートしません。オブジェクト参照は 実際には 4 バイトの整数で、「jvalue」データ構造の「l」サブフィールドは オブジェクトとしてではなく、4 バイトの整数として定義されます。RPG オブジェクト・タイプを jvalue.l サブフィールドに割り当てるには、RPG コンパイラーが オブジェクト参照を整数として処理するようにする プロシージャーおよび「spoofing」プロトタイプを書き込む必要があります。単純に整数パラメーターを 取り、整数を戻す 1 つのプロシージャーを作成します (以下の例ではプロシージャー「refIntConv」)。 次に、プロシージャー・ポインターを使用してこのプロシージャーを呼び出す 2 つのプロトタイプ を作成します。1 つ目のプロシージャーは戻りタイプをオブジェクト・タイプとして定義し (以下の例ではプロシージャー「intToRef」)、もう 1 つのプロシージャーはパラメーターを オブジェクト・タイプとして定義します (以下の例ではプロシージャー「refToInt」)。 オブジェクト・タイプと整数タイプを変換するには、プロトタイプ refToInt または IntToRef のいずれかを呼び出します。

図 1. spoofing プロシージャーが オブジェクト・タイプと整数タイプを変換するためのプロトタイプを持つ /COPY JNICONV_PR
 *----------------------------------------------------------------   
 * refIntConv_procptr: 
 *    This procedure pointer is set to the address of a 
 *    procedure that takes an integer parameter and returns 
 *    an integer.
 *    Since an object refererence is actually an integer, we
 *    can define prototypes that define either the return value
 *    or the parameter as an object reference, to trick the RPG
 *    compiler into allowing the Object reference to be passed 
 *    to or returned from the procedure.
 *    Note: This type of trickery is not normally recommended,
 *       but it is necessary in this case to circumvent the RPG 
 *       restriction against Object subfields.
 *----------------------------------------------------------------   
D refIntConv_name...                                                
D                 c                   'refIntConv'                  
D refIntConv_procptr...                                             
D                 s               *   procptr                       
D                                     inz(%paddr(refIntConv_name))
 *----------------------------------------------------------------   
 * refToInt - convert an object reference to an integer              
 *----------------------------------------------------------------   
D refToInt        pr            10i 0 extproc(refIntConv_procptr)      
D   ref                           o   class(*java:'java.lang.Object')
D                                     value                          
                                                                     
 *----------------------------------------------------------------   
 * intToRef - convert an integer to an object reference              
 *----------------------------------------------------------------   
D intToRef        pr              o   class(*java:'java.lang.Object')
D                                     extproc(refIntConv_procptr)      
D   int                         10i 0 value                     
 
図 2. オブジェクト・タイプと整数タイプを変換するためのプロシージャー
H NOMAIN                                                           
                                                                   
 /COPY JNICONV_PR                                                  

 *----------------------------------------------------------------
 * refIntConv is used with prototypes refToInt and intToRef        
 * to convert between Object and integer types in RPG.             
 * See JNICONV_PR for more details.                               
 *---------------------------------------------------------------- 
D refIntConv      pr            10i 0 extproc(refIntConv_name)     
D    parm                       10i 0 value                        

 *----------------------------------------------------------------
 * The procedure simply returns its parameter.                    
 *---------------------------------------------------------------- 
P refIntConv      B                   export                       
D refIntConv      pi            10i 0                              
D    parm                       10i 0 value                        
 /free                                                             
    return parm;    
 /end-free          
P refIntConv      E 
図 3. 変換プロトタイプの使用
 /copy QSYSINC/QRPGLESRC,JNI
 /copy JNICONV_PR                                                     
D jvals           ds                  likeds(jvalue) dim(5)
D myString        s               o   class(*java:'java.lang.String') 
D newString       pr              o   extproc(*java:'java.lang.String'
D                                           : *constructor)           
D   val                        100a   const varying
 /free
      myString = newString('Hello');                                  
      // Set the myString reference in the first jvalue element
      jvals(1).l = refToInt (myString);                                  
      . . .
      // Set the myString reference from the second jvalue element
      myString = intToRef(jvals(2).l);                                   
      . . .
      return;