Septeni Engineer's Blog

セプテーニエンジニアが綴る技術ブログ

cocos2d-xでiOS/Androidネイティブのメソッドをビルドターゲットごとに呼ぶ

こんにちは、新卒入社からそろそろ1年が経つjoytomoです。
年初に開発者の集まる部署が別会社化し、心機一転業務に励んでいます。
なお新会社では開発者に働きやすい施策がいろいろ進行中のようです。


さて、cocos2d-xでiOS/Androidそれぞれのネイティブ用しか提供されていないライブラリのメソッドなど使うときの方法です。
Sceneファイル内から簡単に呼び出せるようにしてみました。

このような構成としています。
f:id:k_chindamaikul:20150722114546j:plain

C++からObjective-Cメソッドを使うにはObjective-C++経由、
javaメソッドを使うにはjni経由でコールする必要があります。

CallNativeMethods.h
[objc]
#include
#include "cocos2d.h"

using namespace std;
using namespace cocos2d;

class CallNativeMethods
{
public:
static void hogeMethod(string fugaParam);
};
[/objc]

CallNativeMethods.cpp
[objc]
#include "CallNativeMethods.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "CalliOSMethod.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"
#include
#include
//ここで目的のメソッドがあるクラスをパッケージ名から記述します。
#define CLASS_NAME "com/AndroidNativeLibrary/ClassName"
#endif

void CallNativeMethods::hogeMethod(string fugaParam)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
iOSNativeClass::iOSNativeMethod(fugaParam);
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//ここで目的のjavaのメソッドを呼び出しています。ここでは例として引数がstring一つのメソッドとしています。
JniMethodInfo hogeInfo;
if (JniHelper::getStaticMethodInfo(hogeInfo, CLASS_NAME, "androidNativeMethod", "(Ljava/lang/String;)V")) {
jstring fugaParamStr = hogeInfo.env->NewStringUTF(fugaParam.c_str());
hogeInfo.env->CallStaticVoidMethod(hogeInfo.classID, hogeInfo.methodID, fugaParamStr);
hogeInfo.env->DeleteLocalRef(fugaParamStr);
hogeInfo.env->DeleteLocalRef(hogeInfo.classID);
}
#endif
}
[/objc]

Objective-CはAndroidでビルドできないので、
iOSネイティブのメソッドを呼ぶ際には一旦Objective-C++ファイルを噛ませています。

CalliOSMethod.h
[objc]
#include
#include "cocos2d.h"

using namespace std;
using namespace cocos2d;

class iOSNativeClass
{
public:
static void iOSNativeMethod(string fugaParam);
};
[/objc]

CalliOSMehod.mm
[objc]
#include "CalliOSMethod.h"
//呼び出したいヘッダファイルをinclude
#include "iOSNativeLibrary.h"

void iOSNativeClass::iOSNativeMethod(string fugaParam)
{
//ここでやっと目的のObjective-Cのメソッドを呼び出しています。ここでは例として引数がNSSString一つのメソッドとしています。
NSString* fugaParamStr = nil;
if (fugaParam.c_str() != NULL) {
fugaParamStr = [NSString stringWithFormat:@"%s", fugaParam.c_str()];
}
[iOSNativeClass iOSNativeMethod:fugaParamStr];
}
[/objc]

そしてjni/Android.mkのLOCAL_SRC_FILESにCallNativeMethods.cppを追加すれば、
[objc]
CallNative::hogeMethod("abc");
[/objc]
このようにcocos2d-xのSceneからiOS/Androidネイティブのメソッドをビルドターゲットごとに呼ぶことができるようになったはずです。

けっこう無理矢理な気がするので、もっと良い方法があればコメントください。