Java 側から COBOL 側にパラメータを渡す。

 ほとんど COBOL とは関係ない世界になってきていますが、オープン系技術者の活躍どころです。

 前回までの内容でできることといったら Java をトリガとして COBOL プログラムを走らせるぐらいで、面白みというか有用性がほとんどありません。今回は、Java から COBOL にパラメータを渡す方法をご紹介します。これができれば、Java の豊富なインタフェースを用いて COBOL にパラメータを渡せるようになるので使いでがいっきに広がると思います。EJBCOBOL とか、Web サービスで COBOL とか。

 なお、コンパイル方法は前回と同じですのでそちらを参照してください。

 まず、こんな感じの COBOL プログラムがあるとします。外部から 10 バイトの文字列を受け取って、Hello, なんとかと表示するプログラムです。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. hello.
       DATA DIVISION.
       LINKAGE SECTION.
       01 NAME PIC X(10).
       PROCEDURE DIVISION USING NAME.
       DISPLAY "Hello, " NAME.
       EXIT PROGRAM.

 次に Java 側です。byte 配列でパラメータを渡します。注意しなければならないのは、後ろに空白を入れて 10 バイトに合わせなければならないことです。COBOL 界ではあたり前のことですけどね。

package bridge;

public class HelloCobol {
    static {
        // ライブラリのロード
        System.loadLibrary("Hello");
    }

    // ネイティブメソッドの宣言
    public native void sayHello(byte[] name);

    public static void main(String[] args) {
        HelloCobol helloCobol = new HelloCobol();
        byte[] name = "Hoge      ".getBytes();
	
        helloCobol.sayHello(name);
    }
}

 ネイティブメソッドの宣言が前回と違うので、javah コマンドで再度ヘッダファイルを生成しなおしてください。

 最後に C のプログラムです。COBOL プログラムは、リンケージセクションのレベル 1 のものがそのまま引数になります。Java からの引数は、第3引数の jbyteArray になります。これは直接参照できないので、下記の方法で jbyte 配列の先頭ポインタを取得します。jbyte は、unsigned char と同義です。最後に資源のリリースを行います。これによって nameRef の資源が開放され、その内容が Java 側に反映されます。

#include <libcob.h>
#include "bridge_HelloCobol.h"

/* COBOL プログラムのプロトタイプ宣言 */
extern int hello(char*);

JNIEXPORT void JNICALL Java_bridge_HelloCobol_sayHello(JNIEnv *env, jobject obj, jbyteArray name) {
    /* 引数の配列の参照を取得 */
    jbyte *nameRef = (*env)->GetByteArrayElements(env, name, NULL);

    /* COBOL の初期化 */
    cob_init(0, NULL);

    /* COBOL プログラムの実行 */
    hello((char*)nameRef);

    /* 資源のリリース */
    (*env)->ReleaseByteArrayElements(env, name, nameRef, 0);
}

 あとは前回と同じようにコンパイル、リンクを行えば動きます。