19.3.2 JavaプログラムからCOBOLプログラムを呼び出す方法
(1) Java言語での作業
(a) Javaソースプログラムの作成
COBOLプログラムを呼び出すJavaプログラムでは,次の三つのJavaソースファイルを作成する必要があります。
-
mainメソッドを含むJavaプログラム(Javaクラス)
-
COBOLプログラムに対応するJavaプログラム(Javaクラス)
-
COBOLプログラムの初期化・終了処理をするCプログラムに対応するJavaプログラム(Javaクラス)
- mainメソッドを含むJavaプログラム(Javaクラス)
-
Javaアプリケーションは,「static」属性と「public」属性を持つ「main」という名前のメソッドから実行が開始されます。そのため,この「main」メソッドを含むJavaプログラム(Javaクラス)が必要です。
COBOLプログラムの呼び出し,およびサービスルーチンの呼び出しを含む「main」メソッドを含むクラス「DLLtest」を記述したJavaソースファイル「DLLtest.java」の例を次に示します。
- Javaソースファイルの例(DLLtest.java)
public class DLLtest { public static void main (String args[]) { // サービスルーチンを呼び出す // Cプログラムに対応するクラスのインスタンスを生成 DLLcbl2002rt aDLLcbl2002rt = new DLLcbl2002rt (); // 呼び出すCOBOLプログラムに対応する // クラスのインスタンスを生成 DLLclass aDLLclass = new DLLclass (); // COBOLプログラムの実行環境初期化処理をする // サービスルーチンを呼び出す aDLLcbl2002rt.cblgint (); // COBOLプログラムの呼び出し int result = aDLLclass.DLLcobol (10, 20); // COBOLプログラムの実行環境終了処理をする // サービスルーチンを呼び出す aDLLcbl2002rt.cblend (); // Javaプログラムの終了 System.exit (0); } }
- COBOLプログラムに対応するJavaプログラム(Javaクラス)
-
Javaプログラムから他言語プログラムを呼び出す場合には,他言語プログラムに対応するJavaプログラム(Javaクラス)を作成しなければなりません。そのため,呼び出されるCOBOLプログラムに対応するJavaプログラム(Javaクラス)が必要です。
Javaプログラムから呼び出す,他言語プログラムに対応するJavaプログラム(Javaクラス)には,呼び出す他言語プログラムに対応する「native」属性を持つJavaメソッドを定義します。また,他言語プログラムを含むDLLをロードするstatic命令も含んでいる必要があります。
COBOLプログラムに対応するJavaプログラム(Javaクラス)の例と,この例で仮定している名称を次に示します。
- Javaソースファイル(DLLclass.java)
class DLLclass { // 呼び出されるCOBOLプログラムに対応する // メソッドプロトタイプを定義する public native int DLLcobol (int arg1, int arg2); // 呼び出されるCOBOLプログラムを含むDLLをロードする static { System.loadLibrary ("DLLfunc"); } }
表19‒3 例で仮定している名称 名称
意味
DLLcobol
呼び出されるCOBOLプログラムに対応するJavaメソッドのメソッド名
DLLfunc.dll
呼び出されるCOBOLプログラムを含むDLLのファイル名
DLLclass
呼び出されるCOBOLプログラムに対応するJavaメソッドを含むJavaプログラム(Javaクラス)のクラス名
DLLclass.java
DLLclassを記述したソースファイルのファイル名
- 注意事項
-
-
他言語プログラムに対応するJavaメソッドの宣言には,「native」を指定します。「native」指定は,Java言語以外の言語で実装されたメソッドであることを表します。なお,メソッドの本体は記述しません。
-
「native」が指定されたJavaメソッドに対応する他言語プログラムのプログラム名は,Javaメソッド名を変換した名前でなければなりません。詳細は,「19.3.2 JavaプログラムからCOBOLプログラムを呼び出す方法」の「(2) COBOL言語側の作業」を参照してください。
-
「loadLibrary」メソッドの引数には,呼び出す他言語プログラムを含むDLLのファイル名(拡張子は除く)を指定します。
-
- COBOLプログラムの初期化・終了処理をするCプログラムに対応するJavaプログラム(Javaクラス)
-
COBOLプログラムに対応するJavaプログラム(Javaクラス)と同様に,COBOLプログラムの初期化・終了処理を実行するサービスルーチン(CBLGINT/CBLEND)を呼び出すCプログラムに対応するJavaプログラム(Javaクラス)が必要です。
Cプログラムに対応するJavaプログラム(Javaクラス)の例と,この例で仮定している名称を次に示します。
- Javaソースファイルの例(DLLcbl2002rt.java)
class DLLcbl2002rt { public native int cblgint (); public native int cblend (); static { System.loadLibrary ("DLLcbl2002rt"); } }
表19‒4 例で仮定している名称 名称
意味
DLLcbl2002rt
呼び出すCプログラムを含むDLLのファイル名
DLLcbl2002rt
「native」指定を持つJavaメソッドとDLLをロードする処理を含むJavaクラスのクラス名
DLLcbl2002rt.java
Javaクラス「DLLcbl2002rt」を定義したJavaソースファイルのファイル名
(b) Javaソースファイルのコンパイル
作成したJavaソースファイルをコンパイルして,Javaバイトコードファイルを生成します。
次に,(a)で作成したJavaソースファイルのコンパイル指定例を示します。
(c) ヘッダファイルの生成
生成されたJavaバイトコードファイルの中の,他言語プログラムに対応するJavaプログラム(Javaクラス)のJavaバイトコードファイルから,C言語ヘッダファイルを生成します。このヘッダファイルには,「native」指定のあるJavaメソッドに対応するC言語の関数プロトタイプ宣言が含まれています。
サービスルーチンを呼び出すCプログラムは,このヘッダファイルをインクルードする必要があります。このヘッダファイルは,COBOLプログラム作成時にも必要です。
(b)で生成したJavaバイトコードファイル「DLLclass.class」と「DLLcbl2002rt.class」から,C言語ヘッダファイルを生成させる例を次に示します。
- C言語ヘッダファイルの生成指定例
javah -jni DLLclass javah -jni DLLcbl2002rt
上記の指定を実行すると,C言語ヘッダファイル「DLLclass.h」と「DLLcbl2002rt.h」が生成されます。次に,生成された「DLLclass.h」中のメソッド「DLLcobol」の関数プロトタイプ宣言の例を示します。
JNIEXPORT jint JNICALL Java_DLLclass_DLLcobol (JNIEnv *, jobject, jint, jint);
この例では,Javaメソッドに対応して次のようなC言語の関数が作成されたことになります。
関数の要素
内容
関数名
Java_DLLclass_DLLcobol
引数
4個
関数の戻り値の型
jint
- 注意事項
-
-
javahコマンドには,-jniオプションを指定してください。このオプションを指定すると,Java以外の言語によって実装されたメソッドとのインタフェースであるJava言語の他言語インタフェーススタイルのヘッダファイルが生成されます。
-
javahコマンドの引数には,「native」指定のあるJavaメソッドを含む,Javaクラスのクラス名を指定します。
-
(2) COBOL言語側の作業
(a) COBOL原始プログラムの記述
Javaプログラムから実際に呼び出されるCOBOLプログラムのソースファイルを作成します。ここで作成するCOBOLプログラムは,次の条件を満たしている必要があります。
-
COBOLプログラム名は,Javaバイトコードファイルから生成されたヘッダファイル中の,対応するプロトタイプ宣言と同じ名称でなければならない。
-
COBOLプログラム名は,引用符で囲まなければならない。
-
COBOLプログラムの引数,戻り値は,Javaバイトコードファイルから生成したヘッダファイル中の,対応するプロトタイプ宣言と同じ個数でなければならない。
-
COBOLプログラムの引数,戻り値の型は,対応するCOBOLの型でなければならない。
データ型の対応関係については,「19.3.3 Java言語とCOBOL言語のデータ型の対応」を参照してください。
Javaプログラムから呼び出されるCOBOLプログラムの,ソースファイル例を次に示します。
- COBOLプログラムのソースファイル例(DLLfunc.cbl)
IDENTIFICATION DIVISION. PROGRAM-ID. 'Java_DLLclass_DLLcobol'. DATA DIVISION. WORKING-STORAGE SECTION. LINKAGE SECTION. 01 JNIEnv USAGE ADDRESS. …1. 01 jobject USAGE ADDRESS. …1. 01 arg-1 PIC S9(9) USAGE COMP. …2. 01 arg-2 PIC S9(9) USAGE COMP. …2. 01 ret-1 PIC S9(9) USAGE COMP. …3. PROCEDURE DIVISION USING BY VALUE JNIEnv jobject arg-1 arg-2 …4. RETURNING ret-1. *手続き部本体の記述 DISPLAY 'arg-1: ' arg-1. DISPLAY 'arg-2: ' arg-2. COMPUTE ret-1 = arg-1 * arg-2. DISPLAY 'ret-1: ' ret-1. END PROGRAM 'Java_DLLclass_DLLcobol'.
-
COBOLプログラムの仮引数「JNIEnv」「jobject」は,必ず指定してください。これらの引数は,Javaの実行時環境を保持するポインタで,Java言語側とインタフェースの同期をとります。
-
COBOLプログラムの仮引数「arg-1」,「arg-2」は,対応するJavaメソッドの引数「arg1」と「arg2」にそれぞれ対応します。
-
COBOLプログラムの戻り値「ret-1」は,対応するJavaメソッドの戻り値と対応します。なお,対応するJavaメソッドの型がvoidの場合は,RETURNINGを指定しないでください。
-
JavaからCOBOLへの引数は,「値渡し」で渡されます。したがって,COBOL側では仮引数に「BY VALUE」を指定する必要があります。
(b) COBOLソースファイルのコンパイル
作成したCOBOLソースファイルをコンパイルしてstdcall呼び出し規約(Windows(x86) COBOL2002で有効),またはfastcall呼び出し規約(Windows(x64) COBOL2002で有効)のDLLを生成します。
次に,(a)で例に挙げたソースファイル「DLLfunc.cbl」をコマンドプロンプト上からコンパイルする例を示します。
- Windows(x86) COBOL2002の場合
ccbl2002 -Dll,Stdcall -DllInit -MainNotCBL -Bin1Byte -OutputFile DLLfunc.dll DLLfunc.cbl
- Windows(x64) COBOL2002の場合
ccbl2002 -Dll※ -DllInit -MainNotCBL -Bin1Byte -OutputFile DLLfunc.dll DLLfunc.cbl
- 注※
-
Windows(x64) COBOL2002ではfastcall呼び出し規約を使用するため,サブオプションは指定しません。
- 注意事項
-
-
生成するDLLのファイル名は,Javaプログラムで指定したDLLファイル名と同じでなければなりません。
-
コンパイラオプションに,-Dll,Stdcall(Windows(x86) COBOL2002で有効),-Dll(Windows(x64) COBOL2002で有効),および-MainNotCBLオプションの指定が必要です。また,初期化属性を持つDLLを作成したい場合は,-DllInitオプションを指定します。
-
Java言語のデータ型「Boolean」または「byte」をCOBOLプログラムで引数として受け取る場合には,1バイト2進項目を有効とするために-Bin1Byteオプションの指定が必要です。
-
開発マネージャを使用してDLLを生成する場合,最終生成物の種類に「ダイナミックリンクライブラリ」を選び,リンク処理するように指定してください。また,[プロジェクトの設定]メニューの[実行]から,-MainNotCBLオプションを指定してください。指定方法については,マニュアル「COBOL2002 操作ガイド」を参照してください。
-
(3) C言語での操作
(a) Cソースファイルの作成
COBOLプログラムの初期化・終了処理をするサービスルーチン(CBLGINT/CBLEND)を呼び出すCプログラムを作成します。
作成するCプログラムの関数は,Javaバイトコードファイルから生成したC言語ヘッダファイル内の関数プロトタイプ宣言と同じ名称・型・引数である必要があります。
次に,C言語ヘッダファイル「DLLcbl2002rt.h」に対応するCソースファイルの例「DLLcbl2002rt.c」を示します。
- Cソースファイルの例(DLLcbl2002rt.c)
#include <windows.h> #include "DLLcbl2002rt.h" extern int WINAPI CBLGINT(); extern int WINAPI CBLEND(); JNIEXPORT jint JNICALL Java_DLLcbl2002rt_cblgint(JNIEnv *env, jobject obj) { /* サービスルーチンの初期化ルーチンを 呼び出す */ CBLGINT(); } JNIEXPORT jint JNICALL Java_DLLcbl2002rt_cblend(JNIEnv *env, jobject obj) { /* サービスルーチンの終了処理ルーチンを 呼び出す */ CBLEND(); }
ソース内で使用する関数は,実際にJavaバイトコードファイルから生成されたC言語ヘッダファイル(DLLcbl2002rt.h)中の対応する関数プロトタイプ宣言と同じである必要があります。
(4) プログラムの実行
(a) 環境変数の設定
Javaプログラムを実行する前に,Javaプログラム以外の他言語プログラムを含むDLLがあるパス名を,環境変数PATHに指定する必要があります。環境変数PATHの指定例を次に示します。
- 環境変数PATHの指定例
-
-
生成したCOBOLプログラムのDLL「DLLfunc.dll」,およびCプログラムのDLL「DLLcbl2002rt.dll」が,「d:\users\dll」にある場合
set PATH=d:\users\dll;%PATH%
-