OSに依存する処理を行う際に利用するのがJNIです。 これを使えば、OS毎に処理を分けて実装することができます。
主なJniの利用例
今回はcocos2dx[3.x]で、このJNIを実装する方法を紹介します。
利用するコードはGitHubを参考にして下さい。 Github : albatrus/cocos2dx_Jni
Xcode
まずは、XcodeでJavaを呼び出すJniの実装を行います。
iOS/Androidで利用できる共通コードを作成
まずは、1つのメソッドでiOS/Android側共に呼び出せるメソッドを作成します。 以下のように、ファイルを3つ作成して下さい。
- NativeController.h
- NativeController.cpp
- NativeController.mm
Javaのコードを呼び出すJniを利用するファイルを作成
次にJniを利用するファイルを作成します。
- NativeController_JNI.h
- NativeController_JNI.cpp
注意点
[.cpp]のファイルはXcodeがビルドするTargetに含めないで下さい。
[jni.h file not found]というエラーが出た時も、これが原因です。
Jniの仕組み
今回のコードの説明です。 [c]
include "NativeController_JNI.h"
include "platform/android/jni/JniHelper.h"
//パッケージ名を指定
define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
extern "C" {
void sendJni(){
cocos2d::JniMethodInfo methodInfo;
if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo,CLASS_NAME,"sendJNI", "()V"))
{
return;
}
//Android 5.0 Lolipop ではCallStaticObjectMethodではエラーが出ます。
//methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID);
}
void sendJni2(){
cocos2d::JniMethodInfo methodInfo;
if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo,CLASS_NAME,"sendJNI2", "()V"))
{
return;
}
// methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID);
}
} [/c]
以前は呼び出すパッケージ名がプロジェクト毎に違っていたのですが、Ver3.xになり共通したパッケージを利用するようになりました。 ですので#includeに関してはどのプロジェクトも共通です。 [c]
include "platform/android/jni/JniHelper.h"
//パッケージ名を指定
define CLASS_NAME "org/cocos2dx/cpp/AppActivity"
[/c]
呼び出すメソッドの記述
詳しくメソッドを見ていきます。 まずは、[NativeController.cpp]で利用するメソッド作成します。 [c] void sendJni(){
} [/c]
次に、Java側で呼び出すメソッド名を記載します。 [c] void sendJni(){
cocos2d::JniMethodInfo methodInfo; //今回はsendJNI()を呼び出します。 if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo,CLASS_NAME,"sendJNI", "()V")) { return; }
//methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID); methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID);
} [/c]
Eclipse
Ver3.xで、パッケージ名が変わっています。
先どの指定したパッケージ名にメソッドを記載します。 [c] public class AppActivity extends Cocos2dxActivity {
public static void sendJNI(){
Log.d("coocs2dx Jni","Android action 1");
}
public static void sendJNI2(){
Log.d("coocs2dx Jni","Android action 2");
}
} [/c]
これで完了です。
最後に
今回は、Jniを使って呼び出すメソッドに「引数」「戻り値」はありません。 だから非常に簡単なコードが利用できました。 もし、「戻り値」などがひつような場合はこちらを参考にして下さい。 Cocos2d-xにおけるJNI(その2) | ワンダープラネットエンジニア Blog
追記 2015-1-29
[Android 5.0 Lolipop]端末では、下記メソッドが使えません。 [c] // CallStaticObjectMethod エラーが出ます methodInfo.env->CallStaticObjectMethod(methodInfo.classID,methodInfo.methodID);
//CallStaticVoidMethod こちらを利用する methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID); [/c]
【参考】