Setting an Object Reference in the jvalue Structure

The jvalue structure looks like this:

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

The "l" subfield of the jvalue structure represents an Object reference, but RPG does not support subfields of type Object. Since Object references are actually 4-byte integers, the "l" subfield of the "jvalue" data structure is defined as a 4-byte integer rather than as an Object. To assign an RPG Object type to the jvalue.l subfield, you must write a procedure and a "spoofing" prototype that will trick the RPG compiler into treating an object reference as an integer. You create one procedure that simply takes an integer parameter and returns an integer (procedure "refIntConv" in the example below. Then you create two prototypes that call this procedure using a procedure pointer; one procedure defines the return type as type Object (procedure "intToRef" in the example below), and the other procedure defines the parameter as type Object (procedure "refToInt" in the example below). To convert between Object and Integer types, you call either prototype refToInt or IntToRef.

Figure 1. /COPY JNICONV_PR with prototypes for spoofing procedures to convert between Object and integer types
 *----------------------------------------------------------------   
 * 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                     
 
Figure 2. Procedure to convert between Object and integer types
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 
Figure 3. Using the conversion prototypes
 /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;

Feedback