COBOL2002 ユーザーズガイド


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ソースファイルのコンパイル指定例を示します。

Javaソースファイルのコンパイル指定例
javac DLLtest.java
javac DLLclass.java
javac DLLcbl2002rt.java

上記の指定を実行すると,コンパイル後にJavaバイトコードファイル「DLLtest.class」「DLLclass.class」「DLLcbl2002rt.class」が生成されます。

(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'.
  1. COBOLプログラムの仮引数「JNIEnv」「jobject」は,必ず指定してください。これらの引数は,Javaの実行時環境を保持するポインタで,Java言語側とインタフェースの同期をとります。

  2. COBOLプログラムの仮引数「arg-1」,「arg-2」は,対応するJavaメソッドの引数「arg1」と「arg2」にそれぞれ対応します。

  3. COBOLプログラムの戻り値「ret-1」は,対応するJavaメソッドの戻り値と対応します。なお,対応するJavaメソッドの型がvoidの場合は,RETURNINGを指定しないでください。

  4. 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)中の対応する関数プロトタイプ宣言と同じである必要があります。

(b) Cソースファイルのコンパイル

作成したCソースファイルをコンパイルし,DLLを生成します。

次に,(a)で作成したCソースファイルをコンパイルする指定例を示します。

Cソースファイルのコンパイル指定例
cl /LD DLLcbl2002rt.c cbl2k_32.lib

「cbl2k_32.lib」は,必ず指定してください。これは,COBOL2002で使用できるDLLのインポートライブラリです。指定しない場合,リンクエラーとなります。

上記の例を実行すると,「DLLcbl2002rt.dll」が生成されます。

(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%

(b) Javaプログラムの実行

Javaプログラムの実行は,JDKに付属しているJavaインタプリタを使用して実行する方法と,Javaインタプリタを内蔵したWebブラウザから実行する方法があります。

JDK付属のJavaインタプリタを使用して実行する例を次に示します。この場合,「public」属性と「static」属性を持ち,メソッド名が「main」であるメソッドを含むクラスのクラス名(DLLtest)をJavaインタプリタの引数に指定します。

JavaインタプリタでJavaプログラムを実行する例
java DLLtest