ちょっとJNIを試してみたときのメモ

最初にこのサイトJNIメモ(Hishidama's Java native interface Memo)を参考にJNIに挑戦。
Macでのgccを使ったコンパイルとかが、よくわからなくて?(そもそもCとか全然初心者)
最終的にこのサイトJNI helloworld | Adamish | Blogを発見して、その記事を参考に実装、動作しました!
参考までに以下のバージョンです(Mac OS X 10.9.1)

手順は上記のサイトでも書かれていますが、自分のメモとして
1.native methodのみを実装(HelloWorld.java

public class HelloWorld {
    public native int add(int a, int b);
}

2.上記1をコンパイルしてclassファイル(HelloWorld.class)を作成

javac HelloWorld.java

3.上記2のクラスファイルからjavahでCのヘッダーファイル(HelloWorld.h)を作成

javah -jni HelloWorld

4.上記3のヘッダーファイルを使ってcで実装(HelloWorld.c)

#include <jni.h>
#include "HelloWorld.h"

JNIEXPORT jint JNICALL Java_HelloWorld_add
  (JNIEnv *env, jobject obj, jint a, jint b) {
    return a + b;
}

5.上記4(HelloWorld.c)をコンパイル(libHelloWorld.dylib)

gcc -shared -I/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/include/darwin HelloWorld.c -o libHelloWorld.dylib

6.上記1(HelloWorld.java)にNativeMethodを呼び出す実装を追加

public class HelloWorld {
    static {
        System.loadLibrary("HelloWorld");
    }
    public native int add(int a, int b);
    public static void main(String... args) {
        int ans = new HelloWorld().add(1,2);
        System.out.println(String.format("%d + %d = %d", 1, 2, ans));
    }
}

7.上記6(HelloWorld.java)をコンパイル

javac HelloWorld.java

8.上記7でコンパイルしたファイルを実行

java -Djava.library.path=. HelloWorld

9.実行結果

思ったように動作しました。;-)

  • 作成したファイル

ここまでにいろいろエラーがあったのでそれも参考にメモメモ

gccでのコンパイルで「-shared」のオプション指定をしない場合に発生
よくわからなくて「-c」指定でコンパイル

gccでのコンパイルはできるが、その後Java側から実行時にエラー
などなど、いろいろ勉強不足で四苦八苦でした(汗)
そうそう、Java側でloadlibraryでエラーが発生した時に、ファイル名の指定方法を調べていてSystem#mapLibraryNameメソッドの存在を知りました。最初は「libxxx.so」かなとかも思ったのですが、このメソッドで名前を確認できました。

public class Sample {
    public static void main(String... args) {
        String name = System.mapLibraryName("HelloWorld");
        System.out.println(name);
    }
}

・実行結果にファイル名が表示

記載内容で不備、誤りがあればご指摘いただけると幸いです!!!