C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

Android NDKを使う前に知っておいた方が良いメモ

執筆時点のAndroid NDK(r19)について。

知って措いた方良い事

JNIのCバインディングC++バインディングはまったく別物

APIの名前は同じ挙句にC++版でも名前空間つこうて無かったりで、ありがちなC/C++対応と言いつつ実はCっていうパターンかと思いきやC++バインディングでは同名のAPIでパラメーターの数が違ったり、ポインターのポインターがポインターと参照になっていてAPIを使ったユーザー定義部分のコードをCとC++では変える必要があるなど設計がおかしい。

JNIは蛇殺し

JNIのJAVAとCの名前空間の結合ルールが馬鹿なのでユーザー定義でsnake_caseのシンボルを使うと死ぬ。しかもAndroidで実行してランタイムエラーが出現するまで問題は顕在化しない。

この問題に対しsnakerの私は_の代わりに大文字の'X'を使う事にせざるを得なかった。例えば`jni_is_bakuhatsu`は`jniXisXbakuhatsu`として代替した。悪夢的である。

コンパイラーとは何だったのか

未定義のシンボルがあってもコンパイルエラーとかワーニングとか無く、Androidで実行してランタイムエラーが出現するまでtypoすら分からない。

標準ライブラリーは非標準

C++の標準ライブラリーを標準では使えない。(Application.mkにAPP_STLを明示的に定義する必要がある)

C++標準ライブラリーを使う為にはjni/Application.mk(jni/Android.mkでパス指定を特殊化も可能)を作り、APP_STLstlport_staticないしgnustl_staticを明示的に定義しなければならない。

これを定義しないとSTLじゃないのに<string>すら使えない。

g++-4.4.3だからC++11の一部機能を使えるとか無かった

使えるg++は4.4.3なので-std=c++0xをCXXFLAGSに定義するなどすればC++11な機能も一部使える。

しかし、-std=c++0xすると<string>がコンパイルエラー吐くのでstd::stringと併用出来ない。stlport_static使用でもgnustl_static使用でも何れにせよ発症する。

補足的な事

それ、archなら

archlinuxならAURにandroid-sdkandroid-ndkもパッケージがメンテされている

eclipseとか全く必要無い。

コマンド群(android ndk-build ant adb ddms など)を使えば良い。

しかし何故かadbコマンドでuninstallとかまず成功しないからAndroid直接操作してアンインストールしてからinstallするなど妙な癖があったりはする

でっていう?
  • Android爆発!(但し先にもっと不自由なソレとかアレとか爆発!)
  • JAVA爆発!(特にJNIの設計がダメ過ぎるので先ずはJNI爆発!)
  • C++とか言ってるのにC++じゃない処理系爆発!(使えるだけ嬉しいけど爆発!)
ref

その後、Android NDKを使おうとしていた学生さんがブログでrefってくれてた&画像付きの解説してくれてたので参考に。