読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

Cocos2d-xにおけるJNI(その1)

今回のエンジニアブログを担当する村田です。

Cocos2d-xにおいてAndroidのネイティブ連携に必要なJNI(Java Native Interface)についてです。

JNIは、Javaで記述されたプログラムと、C/C++といった他の言語で記述されたネイティブコードを連携するための仕様です。

Cocos2d-xにおいては、

  • C/C++ から Java(Android) を呼び出す時
  • Java(Android) から C/C++ を呼び出す時

に用いられます。

Cocos2d-xのソースを見ながら、JNIの基本的な部分を説明します。
※ 参照バージョン:cocos2d-x-2.1.5

今回は、『Java から C/C++のメソッドを呼び出す』です。

1. nativeメソッドの定義

呼び出すC/C++側の関数をJavaプログラムに定義します。

今回使用するJavaプログラムは

  • パッケージ名「com.example.testjni」
  • クラス名  「TestJniActivity」

と付けます。

TestJniActivity.java

package com.example.testjni;  
  
  :  
 (略)   
  :  
  
public class TestJniActivity extends Cocos2dxActivity {  
  
    private static final String TAG = TestJniActivity.class.getSimpleName();  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
            :  
        必要な処理を記述  
            :  
    }  
  
    // Cocos2d-xでビルドするとlibgame.soが生成されます  
    // libgame.soを読み込みます  
    static {  
        System.loadLibrary("game");  
    }  
  
    // 呼び出すネイティブ関数  
    public native String getSumJni(int x, int y);  
  
    public void methodTest() {  
        // ネイティブ関数を呼び出す  
        String val = getSumJni(1, 6);  
        Log.d(TAG, val);  
    }  
}  

ポイント

  • C/C++の関数を定義する際は native を付ける

2. nativeプログラムの実装

Javaから呼び出される関数は、System.loadLibraryで読み込まれたライブラリ内に実装されている必要があります。
Cocos2d-xの場合、C/C++で記述したプログラムは全てlibgame.soに含まれます。
ゆえに、あまり意識しなくても良いというのが利点です。

では今回は、簡単にmain.cppに実装します。

main.cpp

#include <jni.h>  
  
  :  
 (略)   
  :  
  
jstring Java_com_example_testjni_TestJniActivity_getSumJni(JNIEnv* env, jobject thiz, jint x, jint y)  
{  
    int sum = (int)x + (int)y;  
  
    char buf[256];  
    sprintf(buf, "%d", sum);  
  
    return env->NewStringUTF(buf);  
}  

ポイント

  • Javaとネイティブでは型が異なります
    Javaネイティブ
    booleanjboolean
    bytejbyte
    charjchar
    shortjshort
    intjint
    longjlong
    floatjfloat
    doublejdouble
    Stringjstring
    Objectjobject
    ※ 配列なども記述が異なります。詳細は次回記載します。
  • 関数は次の規則に沿って定義 ・Java_パッケージ名_クラス名_関数名  ※ パッケージ名の"."は"_"に置き換えること ・第一引数、第二引数はお決まり。第三引数からが定義した関数の引数

今回は、ネイティブコードをmain.cppに記述しましたが、メンテナンスなどを考慮すると目的別に専用のクラスを作成した方が良いです。

次回は、C/C++からJavaのメソッドを呼び出す部分について記載します。