LoginSignup
19
20

More than 5 years have passed since last update.

cocos2d-x JNI サンプル集

Last updated at Posted at 2015-12-20

この投稿はモバイルファクトリー Advent Calenaderの20日目のものです。

この記事ではcocos2d-x 3系で、何かと面倒で忘れがちなJNI記法・使用例を記述していきます。

JNIとは

Java Native Interface (JNI) は、Javaプラットフォームにおいて、Javaで記述されたプログラムと、他の言語(たとえばCやC++など)で書かれた、実際のCPUの上で動作するコード(ネイティブコード)とを連携するためのインタフェース仕様である。

wikipediaより引用

メソッドシグネチャ

シグネチャとは

引数の型、引数の数、メソッド名の組み合わせを組み合わせをシグネチャ(シグニチャ)と呼びます。

型対応表

java 型のシグネチャ
void V
byte B
boolean Z
char C
short S
int I
long J
double D
float F
String Ljava/lang/String;
その他javaクラス L + パッケージ/クラス名 + ;

メソッドシグネチャ例

c++ シグネチャ例
void hoge(); "()V"
void hoge(int a); "(I)V"
int hoge(int a) "(I)I"
int hoge(int a, int b) "(II)I"
long hoge(short a, double b) "(SD)J"
boolean hoge(String a); "(Ljava/lang/String;)Z"
boolean hoge(int a[], char b, byte c[] ) "([ab[c)Z"

記法

"(引数)返り値"

  • 引数がない場合未指定
  • 引数を複数持たせる場合、連続してシグネチャを記述する
  • 配列はシグネチャの前に[を記述する

より詳細な情報はOracleのJNI仕様などを見ると良いかと思います。

JNIの記述例は下記サイトが解りやすくまとまっています。
JNIサンプル集 : 技術者のたまごブログ

cocos2d::JniHelper

cocos2d::JniHelperを利用した記述例を記載していきます。

記法

JniHelperのドキュメントが見当たらなかったのですが、基本的にはJNIの関数なので気にしないことにします。


cocos2d::JniMethodInfo methodInfo;
if (cocos2d::JniHelper::getStaticMethodInfo(methodInfo, "名前空間/クラス名", "関数名", "メソッドシグネチャ")) 
{
    // メソッド呼び出し
     methodInfo.env->CallxxxMethod...

    // 開放処理
    methodInfo.env->DeleteLocalRef(methodInfo.classID);
}

インスタンスメソッドも呼べると思うのですが、どうもうまく叩けず...
今回はjava側がstaticメソッドとしたサンプルを作成します。

cocos2d::JniHelper使用例

  • void hoge();
cocos2d::JniMethodInfo methodInfo;
if (cocos2d::JniHelper::getStaticMethodInfo(methodInfo, "JAVA_CLASS_NAME", "hoge", "()V")) 
{
    methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
    methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
  • void hoge(int a, int b);
cocos2d::JniMethodInfo methodInfo;
if (cocos2d::JniHelper::getStaticMethodInfo(methodInfo, "JAVA_CLASS_NAME", "hoge", "(II)V")) 
{
    methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, 1, 2);
    methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
  • String hoge();
std::string ret;

cocos2d::JniMethodInfo methodInfo;
if (cocos2d::JniHelper::getStaticMethodInfo(methodInfo, "JAVA_CLASS_NAME", "hoge", "()Ljava/lang/String;")) 
{
    jobject objResult = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID);
    ret = cocos2d::JniHelper::jstring2string((jstring)objResult); // jstringをstd::stringに変換
    methodInfo.env->DeleteLocalRef(objResult);
    methodInfo.env->DeleteLocalRef(methodInfo.classID);
}

return ret;

実際には下記のようにプラットフォーム別に処理を分けて書くと思います。

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    // jni
#elif(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    // obj-c++
#endif

他プラットフォーム

おわりに

JNI周りはエラーが追いづらいので、ある程度まではコピペ生活が出来ると幸せかなと思っています。
今後も使用例は更新していきます。(サンプル集というには少ないので...

明日はmorigamixさんです!

19
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
20