がおまる開発ブログ

cocos2d-xやlevelhelperを使って iPhone/Androidアプリの作り方を解説します

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

cocos2d-xでjniを使ってみる

jniって面倒くさいですよね(^_^;)
でもやっとけばcocos2d-x ⇔ java間のやり取りはかなり楽になると思います。

先ずはファイルを作ってみましょう。
下記例はClassesフォルダにInterfaceJNI.cppとInterfaceJNI.hファイルを新規で作成しています。

2013061401.png


#include <string.h>
#include "cocos2d.h"

using namespace std;
using namespace cocos2d;

class InterfaceJNI
{
public:
static void func1();
};




#include "InterfaceJNI.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>

// 呼び出すメソッドが書かれているパッケージ名とjavaクラス名
#define CLASS_NAME "com/marnishi/jniTest/jniTest"

void InterfaceJNI::func1()
{
JniMethodInfo t;
// クラス名とメソッド名を指定します。
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func1", "()V")) {
// voidなので、CallStaticVoidMethodで呼ぶ
t.env->CallStaticVoidMethod(t.classID, t.methodID);
// 解放
t.env->DeleteLocalRef(t.classID);
}
}



cocos2d-x側のHelloWorldScene.cppとかで呼び出してみましょう。

#include "HelloWorldScene.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "JNICalls/InterfaceJNI.h"
#endif

USING_NS_CC;

bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}

this->jniLoad();

}

void HelloWorld::jniLoad()
{
// jniはandroid用専用なので、#ifで読み分ける
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
InterfaceJNI::func1();
#endif
}


次にEclipseを起動して、java側の記述を行います。
2013061402.png


package com.marnishi.jniTest;

import org.cocos2dx.lib.Cocos2dxActivity;

import android.os.Bundle;

public class jniTest extends Cocos2dxActivity{

protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}

public static void func1() {
System.out.println("func1 call");
}

static {
System.loadLibrary("game");
}

}


【様々な型の呼び出しや戻り値】
voidだけではなく、他の型などで呼び出す場合のサンプルです。

cocos2d-x側

#include <string.h>
#include "cocos2d.h"

using namespace std;
using namespace cocos2d;

class InterfaceJNI
{
public:
static void func1();
static void func2(int value);
static void func3(bool value);
static void func4(const char *value);
static void func5(const char *value1, int value2, bool value3);
static int func6();
static std::string func7();
};




#include "InterfaceJNI.h"
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#include <android/log.h>

// 呼び出すメソッドが書かれているパッケージ名とjavaクラス名
#define CLASS_NAME "com/marnishi/jniTest/jniTest"

void InterfaceJNI::func1()
{
JniMethodInfo t;
// クラス名とメソッド名を指定します。
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func1", "()V")) {
// voidなので、CallStaticVoidMethodで呼ぶ
t.env->CallStaticVoidMethod(t.classID, t.methodID);
// 解放
t.env->DeleteLocalRef(t.classID);
}
}

/*
// javaでの呼び出し
public static void func1() {
System.out.println("func1 call");
}
*/

// 引数にint型を与える場合(void)
void InterfaceJNI::func2(int value)
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func2", "(I)V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID, value);
t.env->DeleteLocalRef(t.classID);
}
}

/*
public static void func2(int value) {
System.out.println("func2 val=" + value);
}
*/

// 引数にbool型を与えた場合
void InterfaceJNI::func3(bool value)
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func3", "(Z)V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID, value);
t.env->DeleteLocalRef(t.classID);
}
}
/*
public static void func3(boolean value) {
System.out.println("func3 val=" + value);
}
*/

// 引数にcharを渡す場合
void InterfaceJNI::func4(const char *value)
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func4", "(Ljava/lang/String;)V")) {
// ★パラメータがStringの場合はjstringに変換する
// java側は「String」にする。UTF8変換
jstring stringArg1 = t.env->NewStringUTF(value);
t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1);

t.env->DeleteLocalRef(stringArg1);// ★jstringは解放が必要です。
t.env->DeleteLocalRef(t.classID);
}
}
/*
public static void func4(String value) {
System.out.println("func4 val=" + value);
}
*/

// 引数に、char、int、boolの複数を指定する場合
void InterfaceJNI::func5(const char *value1, int value2, bool value3)
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func5", "(Ljava/lang/String;IZ)V")) {
jstring stringArg1 = t.env->NewStringUTF(value1);
t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1, value2, value3);

t.env->DeleteLocalRef(stringArg1);
t.env->DeleteLocalRef(t.classID);
}
}

/*
public static void func5(String value1, int value2, boolean value3) {
System.out.println("func5 val=" + value1 + " int=" + value2 + " bool=" + value3);
}
*/

// 戻り値がint
int InterfaceJNI::func6()
{
int ret = 0;

JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func6", "()I")) {
ret = t.env->CallStaticIntMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}

return ret;
}

/*
public static int func6() {
return 12345;
}
*/

// 戻り値が文字列
std::string InterfaceJNI::func7()
{
std::string ret;
JniMethodInfo t;

if (JniHelper::getStaticMethodInfo(t, CLASS_NAME, "func7", "()Ljava/lang/String;")) {
jstring jStr = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
const char* str = t.env->GetStringUTFChars(jStr, NULL);
ret = str;

t.env->ReleaseStringUTFChars(jStr,str);
t.env->DeleteLocalRef(t.classID);
}

return ret;

}

/*
public static String func7() {
return "本日は晴天なり";
}
*/



これで基礎的部分は抑えられたと思います。
次回はjava→cocos2d-xのメソッドを呼び出す方法です。



スポンサーサイト

コメント

エラーが出てしまう

cocos2d-xで、JNIを使うことになったので、こちらのサイトをコードを練習として打ってみたのですが、エラーが出てしまいました。出た個所は、
void HelloWorld::jniLoad()
{
// jniはandroid用専用なので、#ifで読み分ける
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
InterfaceJNI::func1();//ここです。
#endif
}
Xcodeでは、エラーが出ていないのですが、eclipsで開いたらエラーがでます。
自分は、エンコードやほかの設定ができていないと思うのですが、上手く行きません。
気をつけなければならないポイントなどはございませんか?

  • 2014/06/26(木) 22:29:52 |
  • URL |
  • 大山  #LDnNWMJ6
  • [ 編集 ]

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://gaomar.blog.fc2.com/tb.php/81-0322d792
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。