hyoromoのブログ

iOS/AndroidもしくはCocos2dxネタを書いています

Hello from JNI!

NDKやらにゃなーと思ってので試して見ることにしました。
使用するのは Android NDK, r4 です。r3とr4ではNDKインストール手順が異なりますし、今後また変わるかもしれませんので注意してください。
今回は android-ndk/samples/hello-jni をコピペしながら実行するまでの説明をします。
なんでインポートしないかはインポートしちゃうと自分で新規作成する際に困るので、詰まるなら先に詰まっとけ精神。

NDKインストール手順

ここからOSに応じたNDKをDL、適当なディレクトリに配置する。
DLしたディレクトリまでのpathを設定*1

プロジェクト作成

いつも通りプロジェクトを作成。作成後にプロジェクト直下へ jni フォルダを作成。
その中にAndroid.mk と Cコードを追加。
とりあえず android-ndk/samples/hello-jni を丸ごと持ってくれば分かりやすい。

NDKビルド

mk と c ファイルの編集が終わったらターミナルから以下コマンドを叩くとビルドされる。

ndk-build -B

正常に終了するとプロジェクト直下の libs以下に so ファイルなどが作成される。

デプロイ

いつも通り実行すればデプロイされて "Hello from JNI!" の文字が確認できます。

バッドノウハウ

ビルド時にエラーになる
$ ./ndk-build -C samples/hello-jniAndroid NDK: Your APP_BUILD_SCRIPT points to an unknown file: /Applications/android-ndk/jni/Android.mk    
/Applications/android-ndk/build/core/add-application.mk:98: *** Android NDK: Aborting...    .  Stop.

原因はPATHの指定がおかしかったみたい。PATHの設定し直しで正常に通るようになる。

プロジェクト直下のディレクトリでビルドするとエラーになる
$ ndk-build -B
make: *** No rule to make target `/Users/hyoromo/Project/Android/HelloJni/jni/HelloJni.c', needed by `/Users/hyoromo/Project/Android/HelloJni/obj/local/armeabi/objs/HelloJni/HelloJni.o'.  Stop.

Android.mkの設定でいくつか定数が設定できますが、設定値の設定規則がおかしいのが原因です。
例えば、LOCAL_MODULE := HelloJni はエラーとなるので LOCAL_MODULE := hello-jni などとする。

apkデプロイ時にエラーになる
FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: stringFromJNI

cのコードでjava側のnative変数を指定する際に、ルールに則って無いとエラーになります。
java_[パッケージ名(.は_に置き換え)]_ソース名_変数名
例)Java_com_example_hellojni_HelloJni_stringFromJNI

参考サイト

たすかりました。ありがとうございます。
Android NDK r4 -最近のちょっ得

*1:例えば/Applications/android-ndk