このサンプル・プログラムは、Java と PL/I の間で 双方向にストリングの受け渡しを行います。jPassString.java プログラムの完全なリストは、図 82 を参照してください。Java 部分には、1 つの Java クラス jPassString.java があります。PL/I で書かれたネイティブ・メソッドは、passString.pli に含まれています。最初のサンプル・プログラムで説明したことの多くが、 このサンプル・プログラムにも当てはまります。 このサンプル・プログラムについては、新しい面と異なる面だけ を説明します。
このサンプル・プログラムのネイティブ・メソッドは、 次のとおりです。
public native void pliShowString();
このサンプル・プログラムのネイティブ・ライブラリーをロード する Java ステートメントは、次のとおりです。
static {
System.loadLibrary("passString");
}
jPassString クラスには、クラスのインスタンスを生成して ネイティブ・メソッドを呼び出す main メソッドも含まれ ています。 main メソッドは jPassString のインスタンスを生成し、 pliShowString() ネイティブ・メソッドを呼び出します。
このサンプル・プログラムは、ストリングの入力をユーザーに促し、 コマンド行からその値を読み込みます。この作業は、図 82 に 示す try/catch ステートメント内で行われます。
// Read a string, call PL/I, display new string upon return
import java.io.*;
public class jPassString{
/* Field to hold Java string */
String myString;
/* Load the PL/I native library */
static {
System.loadLibrary("passString");
}
/* Declare the PL/I native method */
public native void pliShowString();
/* Main Java class */
public static void main(String[] arg) {
System.out.println(" ");
/* Instantiate Java class and initialize string */
jPassString myPassString = new jPassString();
myPassString.myString = " ";
/* Prompt user for a string */
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
/* Process until 'quit' received */
while (!myPassString.myString.equalsIgnoreCase("quit")) {
System.out.println(
"From Java: Enter a string or 'quit' to quit.");
System.out.print("Java Prompt > ");
/* Get string from command line */
myPassString.myString = in.readLine();
if (!myPassString.myString.equalsIgnoreCase("quit"))
{
/* Call PL/I native method */
myPassString.pliShowString();
/* Return from PL/I and display new string */
System.out.println(" ");
System.out.println(
"From Java: String set by PL/I is: "
+ myPassString.myString );
}
}
} catch (IOException e) {
}
}
}Java コードをコンパイルするコマンドは、次のとおりです。
javac jPassString.java
PL/I "Hello World" サンプル・プログラムの作成についての説明が、 このプログラムにもすべて当てはまります。
このプログラムの PL/I プロシージャー名は、 Java_jPassString_pliShowString です。
サンプル・プログラムの完全なプロシージャー・ステートメントは、 次のとおりです。
Java_jPassString_pliShowString:
Proc( JNIEnv , myjobject )
external( "Java_jPassString_pliShowString" )
Options( FromAlien NoDescriptor ByValue );
Java ネイティブ・インターフェースの PL/I 定義を含む 2 つの PL/I インクルード・ファイルは、ibmzjni.inc およびこれにインクルードされる ibmzjnim.inc です。これらのインクルード・ファイルは以下のステートメントでインクルードされます。
%include ibmzjni;
ibmzjni および ibmzjnim インクルード・ファイルは、 PL/I SIBMZSAM データ・セットの中に提供されています。
完全な PL/I プログラムは、図 83 に示してあります。 このサンプル PL/I プログラムは、JNI を介していくつかの呼び出しを 行います。
開始時に、呼び出し側 Java オブジェクト myObject への 参照が PL/I プロシージャーに渡されます。 PL/I プログラムはこの参照を使用して、呼び出し側からの情報を 取得します。最初の情報は、GetObjectClass JNI 関数を使用して 検索される呼び出し側オブジェクトのクラスです。 このクラス値は、対象となる Java オブジェクト内の Java ストリング・ フィールドの ID を取得するために、GetFieldID JNI 関数に よって使用されます。 この Java フィールドは、フィールド名 myString、および JNI フィールド 記述子 Ljava/lang/String; (フィールドが Java ストリング・ フィールドであることを示す) の指定によってさらに詳細に識別されます。 その後、Java ストリング・フィールドの値が GetObjectField JNI 関数を使用して検索されます。PL/I が Java ストリング値を 使用するには、事前にこの値をアンパックして PL/I が解釈できる形式に する必要があります。 GetStringUTFChars JNI 関数を使用して、 Java ストリングが PL/I varyingz ストリングに変換され、 このストリングが PL/I プログラムによって表示されます。
取得した Java ストリングを表示した後、PL/I プログラムは、 呼び出し側 Java オブジェクト内のストリング・フィールドの更新に使用 する PL/I ストリングの入力をユーザーに促します。 PL/I ストリングの値は、NewString JNI 関数を使用 して Java ストリングに変換されます。 この新しい Java ストリングを使用して、SetObjectField 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_passString_pliShowString:
Proc( JNIEnv , myJObject )
external( "Java_jPassString_pliShowString" )
Options( FromAlien NoDescriptor ByValue );
%include ibmzjni;
Dcl myBool Type jBoolean;
Dcl myClazz Type jClass;
Dcl myFID Type jFieldID;
Dcl myJObject Type jObject;
Dcl myJString Type jString;
Dcl newJString Type jString;
Dcl myID Char(9) Varz static init( 'myString' );
Dcl mySig Char(18) Varz static
init( 'Ljava/lang/String;' );
Dcl pliStr Char(132) Varz Based(pliStrPtr);
Dcl pliReply Char(132) Varz;
Dcl pliStrPtr Pointer;
Dcl nullPtr Pointer;
Display(' ');
/* Get information about the calling Class */
myClazz = GetObjectClass(JNIEnv, myJObject);
/* Get Field ID for String field from Java */
myFID = GetFieldID(JNIEnv, myClazz, myID, mySig );
/* Get the Java String in the string field */
myJString = GetObjectField(JNIEnv, myJObject, myFID );
/* Convert the Java String to a PL/I string */
pliStrPtr = GetStringUTFChars(JNIEnv, myJString, myBool );
Display('From PLI: String retrieved from Java is: ' || pliStr );
Display('From PLI: Enter a string to be returned to Java:' )
reply(pliReply);
/* Convert the new PL/I string to a Java String */
newJString = NewString(JNIEnv, trim(pliReply), length(pliReply) );
/* Change the Java String field to the new string value */
nullPtr = SetObjectField(JNIEnv, myJObject, myFID, newJString);
End;
end;次のコマンドを使用して、PL/I サンプル・プログラムをコンパイルします。
pli -c passString.pli
次のコマンドを使用して、生成された PL/I オブジェクト・デックを 共用ライブラリーにリンクします。
c89 -o libpassString.so passString.o
PL/I 共用ライブラリーの名前には必ず lib 接頭部を 付けてください。そうしないと、Java クラス・ローダーはライブラリーを 検出できません。