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.
*----------------------------------------------------------------
* 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
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
/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;