プログラミング, JDK

JavaとC言語の連携

JavaとC言語との連携については過去にも述べていますが,改めて紹介します。現在,公式リリースされている機能ではJNI(Java Native Interface)を使います。最新のJDKにプレビューとして含まれているForeieng Function and Memory APIが正式リリースされると,より簡便に連携できるようになると期待されます。

以下のシェル(jni.sh)でソースプログラムを生成してコンパイルし実行します。public static native int add(int a, int b);という部分で,ネイティブ関数を呼び出すことを宣言しておき,javacコマンドに-hオプションをつけてC言語のヘッダファイルを生成します。このヘッダファイルにはネイティブ関数のプロトタイプ宣言JNIEXPORT jint JNICALL Java_JniAdd_add(JNIEnv*, jclass, jint jint)が含まれているので,これに倣ってCプログラムを作成します。単に2つの引数を足し算して返すだけのものです。Cプログラムをコンパイルしてライブラリを作成します。ライブラリのファイル名はLinuxの場合はlibXXX.soという命名にする必要があるようです。Java側でSystem.loadLibrary(“XXX”)を実行するとJava VMに読み込まれて実行できるようになります。

#!/bin/bash
LIB=lib
mkdir -p $LIB
cat << EOS > JniAdd.java
public class JniAdd
{
    public static void main(String[] args)
    {
        System.out.println("START");
        System.loadLibrary("JniAdd");
        int result = add(1, 2);
        System.out.println(String.format("add(1,2)=%d", result));
        System.out.println("END");
    }
    public static native int add(int a, int b);
}
EOS
javac -h . JniAdd.java
cat << EOF > JniAdd.c
#include "JniAdd.h"
JNIEXPORT jint JNICALL Java_JniAdd_add(JNIEnv* env, jclass clazz, jint x, jint y)
{
     return x + y;   
}
EOF
gcc -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux/ -o $LIB/libJniAdd.so JniAdd.c

java -classpath . -Djava.library.path=$LIB JniAdd