研究でJavaからCのプログラムを呼び出す必要がありましたので、JNIとJNAについて勉強してみました。メモまで残しておきます。
■JNI
public class TestJNI { public native int add(int a, int b); }
- ビルドする。
javac TestJNI.java
- javahでヘッダーファイル(TestJNI.h)作成する
javah -classpath . -d . TestJNI
- TestJNI.hよりプロトタイプ宣言に仮引数を追加してCファイル(test_jni.c)にコピーして関数呼び出し部を実装する。(ポイント:C関数を呼び出す前後にJavaとCのプリミティブ型を対応づける処理が必要←ここが面倒)
int add(int a, int b) //既存の関数 { return (a + b); } JNIEXPORT jint JNICALL Java_Test_add (JNIEnv *env, jobject me, jint aj, jint bj) { return add(aj, bj); }
- 動的ライブラリを作成する。
gcc -I /System/Library/Frameworks/JavaVM.framework/Headers -dynamiclib -o libtest_jni.dylib test_jni.c
public class TestJNI { public native int add(int a, int b); public static void main(String [] args) { System.loadLibrary("test_jni"); TestJNI me = new TestJNI(); System.out.println(me.add(100, 200)); } }
- 実行する。
java TestJNI
■JNA
- 事前準備 twall / jna https://github.com/twall/jna よりjna.jar(Version 4.1.0)をダウンロードして、/System/Library/Java/Extensions/にコピーする。
- C関数(test_jna.c)を作成する。
int add(int a, int b) { return (a + b); }
- ビルドする。
gcc -dynamiclib -o libtest_jna.dylib test_jna.c
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Platform; public class TestJNA { public interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.loadLibrary("test_jna", CLibrary.class); int add(int a, int b); } public static void main(String[] args) { System.out.println(CLibrary.INSTANCE.add(100, 200)); } }
参考サイト
* ひしだま's ホームページ JNI(Java Native Interface)http://www.ne.jp/asahi/hishidama/home/tech/java/jni.html
* Mac OSXでダイナミックライブラリdylibを作ったり使ったりする方法 http://blog.katty.in/4346#