Java側でやる事
モジュールをロードする
System.loadLibraryメソッドを使ってライブラリをロードする。
staticでなくてもよいが、netiveメソッドが呼ばれる前にロードする必要がある。
public class MainActivity extends Activity { static { System.loadLibrary("hello-jni"); } }
指定するモジュール名は以下の通り。
■gradleを使う場合
./app/build.gradleの[android.ndk]の[moduleName]で指定するモジュール名
model { android.ndk { moduleName = "hello-jni" } }
■android.mkを使う場合
LOCAL_MODULEで指定するモジュール名
LOCAL_MODULE := hello-jni
ネイティブに置き換えるメソッドを作る
nativeキーワードを使ってメソッドを定義する。
package aaa.bbb_ccc; public class MainActivity extends Activity { static { System.loadLibrary("hello-jni"); } public native String testJNI(); }
C++側でやる事
命名規約
Java側のnativeキーワードで定義されたメソッドをC++側で実装する場合、以下の規約に従う。
Java_[パッケージ名]_[クラス名]_[メソッド名]
※パッケージ名に「.(ピリオド)」がある場合は「_(アンダーバー)」へ置きかえる
※パッケージ名に「_(アンダーバー)」がある場合は「_1」へ置きかえる
例)
aaa.bbb_cccパッケージ、Dddクラス、eeeメソッドの場合
↓
Java_aaa_bbb_1ccc_Ddd_eee
ヘッダーファイル
C言語でコーディングする場合は必要ないが、C++の場合は「extern "C"」で宣言する必要がある。
ちなみに「javah.exe」を使ってヘッダーファイルを作成する事も出来る。
#include <jni.h> #ifdef __cplusplus extern "C" { #endif JNIEXPORT jstring JNICALL Java_aaa_bbb_1ccc_MainActivity_testJNI( JNIEnv* env, jobject thiz ); #ifdef __cplusplus } #endif
2つの引数は固定で、3つ目以降が自身で定義した引数になる。
第1引数:JNI関連の関数を使う時に必要なオブジェクト
第2引数:このメソッドを持つJavaのクラスオブジェクト(上記例の場合MainActivity)
ソースファイル
#include <jni.h> jstring Java_aaa_bbb_1ccc_MainActivity_testJNI( JNIEnv* env, jobject thiz ) { return env->NewStringUTF("Hello from JNI !"); }
コメントをお書きください