このサンプル・プログラムは、Java と PL/I の間で 双方向に整数の受け渡しを行います。jPassInt.java プログラムの完全なリストは、図 84 を参照してください。Java 部分には、1 つの Java クラス jPassInt.java があります。PL/I で書かれたネイティブ・メソッドは、passInt.pli に含まれています。最初のサンプル・プログラムで説明したことの多くが、 このサンプル・プログラムにも当てはまります。 このサンプル・プログラムについては、新しい面と異なる面だけ を説明します。
このサンプル・プログラムのネイティブ・メソッドは、 次のとおりです。
public native void pliShowInt();
このサンプル・プログラムのネイティブ・ライブラリーをロード する Java ステートメントは、次のとおりです。
static {
System.loadLibrary("passInt");
}
jPassInt クラスには、クラスのインスタンスを生成して ネイティブ・メソッドを呼び出す main メソッドも含まれ ています。 main メソッドは jPassInt のインスタンスを生成し、 pliShowInt() ネイティブ・メソッドを呼び出します。
このサンプル・プログラムは、整数の入力をユーザーに促し、 コマンド行からその値を読み込みます。この作業は、図 84 に 示す try/catch ステートメント内で行われます。
// Read an integer, call PL/I, display new integer upon return
import java.io.*;
import java.lang.*;
public class jPassInt{
/* Fields to hold Java string and int */
int myInt;
String myString;
/* Load the PL/I native library */
static {
System.loadLibrary("passInt");
}
/* Declare the PL/I native method */
public native void pliShowInt();
/* Main Java class */
public static void main(String[] arg) {
System.out.println(" ");
/* Instantiate Java class and initialize string */
jPassInt pInt = new jPassInt();
pInt.myInt = 1024;
pInt.myString = " ";
/* Prompt user for an integer */
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
/* Process until 'quit' received */
while (!pInt.myString.equalsIgnoreCase("quit")) {
System.out.println
("From Java: Enter an Integer or 'quit' to quit.");
System.out.print("Java Prompt > ");
/* Get string from command line */
pInt.myString = in.readLine();
if (!pInt.myString.equalsIgnoreCase("quit"))
{
/* Set int to integer value of String */
pInt.myInt = Integer.parseInt( pInt.myString );
/* Call PL/I native method */
pInt.pliShowInt();
/* Return from PL/I and display new string */
System.out.println(" ");
System.out.println
("From Java: Integer set by PL/I is: " + pInt.myInt );
}
}
} catch (IOException e) {
}
}
}Java コードをコンパイルするコマンドは、次のとおりです。
javac jPassInt.java
PL/I "Hello World" サンプル・プログラムの作成についての説明が、 このプログラムにもすべて当てはまります。
このプログラムの PL/I プロシージャー名は、 Java_jPassInt_pliShowInt です。
サンプル・プログラムの完全なプロシージャー・ステートメントは、 次のとおりです。
Java_passNum_pliShowInt:
Proc( JNIEnv , myjobject )
external( "Java_jPassInt_pliShowInt" )
Options( FromAlien NoDescriptor ByValue );
Java ネイティブ・インターフェースの PL/I 定義を含む 2 つの PL/I インクルード・ファイルは、ibmzjni.inc およびこれにインクルードされる ibmzjnim.inc です。これらのインクルード・ファイルは以下のステートメントでインクルードされます。
%include ibmzjni;
ibmzjni および ibmzjnim インクルード・ファイルは、 PL/I SIBMZSAM データ・セットの中に提供されています。
完全な PL/I プログラムは、図 85 に示してあります。 このサンプル PL/I プログラムは、JNI を介していくつかの呼び出しを 行います。
開始時に、呼び出し側 Java オブジェクト myObject への 参照が PL/I プロシージャーに渡されます。 PL/I プログラムはこの参照を使用して、呼び出し側からの情報を 取得します。最初の情報は、GetObjectClass JNI 関数を使用して 検索される呼び出し側オブジェクトのクラスです。 このクラス値は、対象となる Java オブジェクト内の Java 整数 フィールドの ID を取得するために、GetFieldID JNI 関数に よって使用されます。 この Java フィールドは、フィールド名 myInt、および JNI フィールド 記述子 I (フィールドが整数フィールドであることを示す) の 指定によってさらに詳細に識別されます。 その後、Java 整数フィールドの値が GetIntField JNI 関数を使用して検索され、PL/I プログラムによって表示されます。
取得した Java 整数を表示した後、PL/I プログラムは、 呼び出し側 Java オブジェクト内の整数フィールドの更新に使用 する PL/I 整数の入力をユーザーに促します。この PL/I 整数値を使用して、 SetIntField JNI 関数によって呼び出し側 Java オブジェクトの 整数フィールドが更新されます。
PL/I プログラムが終了すると Java に制御が戻され、 新しく更新された Java 整数が Java プログラムによって表示されます。
*Process Limits( Extname( 100 ) ) Margins( 1, 100 ) ;
*Process Display(Std) Dllinit Extrn(Short);
*Process Rent Default( ASCII IEEE );
plijava_demo: package exports(*);
Java_passNum_pliShowInt:
Proc( JNIEnv , myjobject )
external( "Java_jPassInt_pliShowInt" )
Options( FromAlien NoDescriptor ByValue );
%include ibmzjni;
Dcl myClazz Type jClass;
Dcl myFID Type jFieldID;
Dcl myJInt Type jInt;
dcl rtnJInt Type jInt;
Dcl myJObject Type jObject;
Dcl pliReply Char(132) Varz;
Dcl nullPtr Pointer;
Display(' ');
/* Get information about the calling Class */
myClazz = GetObjectClass(JNIEnv, myJObject);
/* Get Field ID for int field from Java */
myFID = GetFieldID(JNIEnv, myClazz, "myInt", "I");
/* Get Integer value from Java */
myJInt = GetIntField(JNIEnv, myJObject, myFID);
display('From PLI: Integer retrieved from Java is: ' || trim(myJInt) );
display('From PLI: Enter an integer to be returned to Java:' )
reply(pliReply);
rtnJInt = pliReply;
/* Set Integer value in Java from PL/I */
nullPtr = SetIntField(JNIEnv, myJObject, myFID, rtnJInt);
End;
end;次のコマンドを使用して、PL/I サンプル・プログラムをコンパイルします。
pli -c passInt.pli
次のコマンドを使用して、生成された PL/I オブジェクト・デックを 共用ライブラリーにリンクします。
c89 -o libpassInt.so passInt.o
PL/I 共用ライブラリーの名前には必ず lib 接頭部を 付けてください。そうしないと、Java クラス・ローダーはライブラリーを 検出できません。