これが確定しちゃうと、当分は今みたいにダラダラ自分の好きなものを作るって感じじゃなくなるけど、目の前にチャンスが転がってるなら生かしたいよね。
とまあ、どう転んだにしろ、今のペースのままだと人としてダメになる気がするので、これを機に何かと巻きで行くことにします。
で、備忘録は忘れないうちに書かないと忘れるので Android と iPhone の備忘録はちょくちょく書いていきたい訳ですが、ちゃんと書こうとするとすぐバテるので小ネタを一つづついく方針で。
あと今に始まった事じゃないですが、技術的な事を書くときはプログラマ以外 (というかピンポイントでそれを検索しにきた人以外) の事は想定せずに書きますので、
2012.04.19追記
タイトルにタグは何かと面倒なので、「続きを読む」に(開発者向け)と着けることにします。
という事で、準備はいいですか?。今回はとりあえず AndroidNDK で組むために参考になったページと覚え書きで。
NDK 関連で参考になったページ
- EclipseからAndroid NDKのコードをビルドする
- ビルドするたびに Cygwin から ndk-build とか効率悪すぎるので、これは必須ですね。これでやっと開発する気になります。でもプロジェクトを作るたびにこれ設定するの非常にめんどいんだけど、なんとかならんものか。
- Android NDK で既存の C コードを再利用する
- NDK の最も典型的な使い方であろう、巨大データの処理ですね。ああ、NDKってこういう風に使うものなのか、と分かります。2つ目以降のフィルタサンプルは本題と関係ないので要らないと思う。
- UsefullCode.net
- ここはホント知りたい事をいろいろやってくれてて助かりました。ライブラリ化とか、既存のライブラリの組み込みとか。今後もお世話になるかと。
- JNI(Java Native Interface)
JNIのC言語/C++側のコーディング - Java と C/C++ の接点となる JNI の詳しい使い方。ただ関数呼ぶだけなら知らなくても問題ないけど、ちょっと凝った事をしようとすると必要になります。
NDK で組んで分かったこと
- 現在リリースされてる AndroidNDK は C/C++ だけの実装も可能になったみたいだけど(真面目に調べてませんが)、まだ先駆者も少ないようだし、OSに近い部分は素直に Java で組んだ方が悩まずに済むので、僕は今のところ Java と C++ のハイブリッドで行くつもり。
アクティビティやイベント処理、フレームの時間管理とかは Java側で行い、1フレーム内に行う全てのゲーム処理と OpenGL での描画は C++ でやる。これだけでもゲームアルゴリズムは Android と iPhone で同じ C++ ソースを使いまわせるので十分。 - Android 端末は機種ごとに性能差がありすぎて、固定fpsでの描画は期待できないので、固定fpsの動作スレッドと、非同期の描画スレッドに分けたんだけど、NDK 内でスレッド立てたり同期する方法が分からんので (少なくとも日本語の情報は見つからんかった)、その辺は全部 Java 側で管理した。書くと長くなるのでまた後日。
- Java から C/C++ の関数を呼ぶのは簡単。逆に C/C++ から Java のメソッドを呼ぶのは可能だけど、ものすごく面倒だし超効率悪そう。可能な限り使わない設計で (今のところ不使用)。
あと、int や float などのプリミティブ型以外を C/C++ に渡すのもかなり面倒なので、多少引数が多くなってもプリミティブ型だけでやりとりしたほうが楽な気がする。 - Java と C/C++ でのやり取りを行う JNI 関数は必ずC規約でないといけない。ソースの拡張子を cpp にしてしまうと C++ 規約でビルドされてしまい、ビルドエラーは出ないが、起動して Java から呼ぶと何も言わずに即死する。
cpp ファイル内で JNI 関数を記述するなら以下のどちらかで。extern "C" { JNI関数はこの中にまとめて宣言、定義 } または extern "C" JNI関数
- 特に何もせずに C/C++ のソースをビルドしたところ、NDK に含まれるバージョンのうち、一番古いバージョン (android-3 とか) でビルドされてしまい困った。
ビルドに使用する NDK のバージョンを指定するには、jni のソースフォルダに Application.mk ファイルを作り、以下のように指定 (以下は android-8 (Android 2.2) の場合)この件について調べてたら、「AndroidManifest.xml の内容を見て勝手に判断してくれる」 みたいな記事もあったんだけど、なぜかウチの環境ではダメみたい。なんで?APP_PLATFORM := android-8