native修飾子を使ってみる(JNI)
javaの勉強を始めた頃に 存在を知ったnative修飾子。
java.lang.System
のソースなどなど 結構使われていたので、ちょっと学んでみました。
以下をはじめ、いろんな情報源を参考にさせてもらいました。
link
そもそもnative修飾子とは
nativeのメソッドは一般的にCのような別の言語で書かれた プラットホームに依存するコードにて実装されます(超意訳)
プラットホームに依存した方が 高速な演算の実現は可能、だけど
一方で環境ごとのライブラリが必要になるから “Write once, run anywhere"の思想からは外れる。
まあ元々WORAは言うほどでもないそうですが。
JNIとは
link
Javaネイティブメソッドを書いたり、 Java仮想マシンをネイティブアプリケーションに組み込む 標準プログラミングインターフェース。
JREに含まれてます。
とりあえず試してみる
Javaでnativeメソッドを書いてみる
package hoge; public class Hoge { // staticイニシャライザ static { // 共有ライブラリを読み込む System.loadLibrary("<span style="color:#FF0000">HogeHoge</span>"); } public static void main(String[] args) { Hoge hoge = new Hoge(); hoge.call(); } // natice修飾子を付与したメソッド // 処理内容は記載しない(interface的な感じ) public <span style="color:#FF0000">native</span> void call(); }
普通にclassを生成する
javac hoge/Hoge.java
classファイルからヘッダファイルを生成する
javah -jni hoge.Hoge
結果として、以下のファイルが出力される。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class hoge_Hoge */ #ifndef _Included_hoge_Hoge #define _Included_hoge_Hoge #ifdef __cplusplus extern "C" { #endif /* * Class: hoge_Hoge * Method: call * Signature: ()V */ JNIEXPORT void JNICALL Java_hoge_Hoge_call (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
実装コードを作成する
#include "hoge_Hoge.h" JNIEXPORT void JNICALL Java_hoge_Hoge_call (JNIEnv *env, jobject obj) { printf("Hello, World!"); }
ライブラリを作る
僕の環境はMacOSXなのですが、 どうやらライブラリというのは各プラットフォームで色々違うようで。
例えば、WindowsだとDLL形式だとか、Linuxだとlib〜.soだとか。
このあたりは別途詳しく調べるとして、 Macだとdylibというらしいです。
gcc -shared -I /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/include -o lib<span style="color:#FF0000">HogeHoge</span>.dylib hoge_Hoge.c
- sharedは共有ライブラリを作るオプション
- -Iは使用するinclude対象を見に行く先。 今回は"jni.h"とそこから参照される"jni_md.h"が必要になるみたい。 find / -name “jni*.h"で探したけど、どうもJDKのinclude及びinclude/darwinにあるみたい。 sudo ln -sでinclude直下にjni_md.hのシンボリックリンクを作りました。
- Macの場合、共有ライブラリはlib.dylibにしないといけないみたい。 そして、の部分がSystem.loadLibraryの引数になる、と…。
実行する
java -Djava.library.path=. hoge.Hoge
実行結果
hoge$java -Djava.library.path=. hoge.Hoge Hello, World!%