エンジニア

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

投稿日:2013年9月3日 更新日:

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

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 ネイティブ
    boolean jboolean
    byte jbyte
    char jchar
    short jshort
    int jint
    long jlong
    float jfloat
    double jdouble
    String jstring
    Object jobject

    ※ 配列なども記述が異なります。詳細は次回記載します。

  • 関数は次の規則に沿って定義
    ・Java_パッケージ名_クラス名_関数名
     ※ パッケージ名の"."は"_"に置き換えること
    ・第一引数、第二引数はお決まり。第三引数からが定義した関数の引数

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

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

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-

© WonderPlanet Inc.