C++でObjC/Java連携しようとすると、グルーコードを書いたりPluginXを使ったりする方法がありますが、記述量や設定が複雑になりがちです。開発言語にLuaを使っている場合これらの複雑な部分は既に書かれており、Luaからから呼び出せるインターフェースも提供されています。
ObjC
LuaからObjCのメソッドを呼び出すにはluaocを使います。例えば本家のテストコードは次のようになっています。
@interface LuaObjectCBridgeTest : NSObject
...
+ (int) addTwoNumbers:(NSDictionary *)dict;
...
@end
+ (int) addTwoNumbers:(NSDictionary *)dict
{
int num1 = [[dict objectForKey:@"num1"] intValue];
int num2 = [[dict objectForKey:@"num2"] intValue];
return num1 + num2;
}
local targetPlatform = cc.Application:getInstance():getTargetPlatform()
...
if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or (cc.PLATFORM_OS_MAC == targetPlatform) then
local args = { num1 = 2 , num2 = 3 }
local luaoc = require "cocos.cocos2d.luaoc"
local className = "LuaObjectCBridgeTest"
local ok,ret = luaoc.callStaticMethod(className,"addTwoNumbers",args)
if not ok then
Director:getInstance():resume()
else
print("The ret is:", ret)
end
end
ObjCで定義したaddTwoNumbersをluaoc.callStaticMethodで呼び出しています。引数はluaのオブジェクトがNSDictionaryに、戻り値は呼び出しの成功と値が返ってきます。
引数には関数を渡すこともでき、ObjCから呼び出せます。
#include "CCLuaBridge.h"
...
+ (void)callbackLua:(NSDictionary *)dict;
{
int scriptHandler = [[dict objectForKey:@"scriptHandler"] intValue];
LuaBridge::pushLuaFunctionById(scriptHandler);
LuaStack *stack = LuaBridge::getStack();
stack->pushString("success");
stack->executeFunction(1);
LuaBridge::releaseLuaFunctionById(scriptHandler);
}
local function callback(param)
if "success" == param then
print("object c call back success")
end
end
luaoc.callStaticMethod(className,"callbackLua", {scriptHandler = callback } )
引数にluaの関数を渡した場合ObjC側では数値が渡ってくるので、その数値を使って関数を呼び出します。使い終わった関数はreleaseLuaFunctionByIdで解放しないとメモリに残ったままになってしまうので注意が必要です。
Java
Javaの場合もObjCと同じように、luajを使います。
package com.cocos2dx.sample.LuaJavaBridgeTest;
import org.cocos2dx.lib.Cocos2dxLuaJavaBridge;
public class LuaJavaBridgeTest
{
public static int addTwoNumbers(final int num1,final int num2){
return num1 + num2;
}
...
}
if (cc.PLATFORM_OS_ANDROID == targetPlatform) then
local args = { 2 , 3}
local sigs = "(II)I"
local luaj = require "cocos.cocos2d.luaj"
local className = "com/cocos2dx/sample/LuaJavaBridgeTest/LuaJavaBridgeTest"
local ok,ret = luaj.callStaticMethod(className,"addTwoNumbers",args,sigs)
if not ok then
print("luaj error:", ret)
else
print("The ret is:", ret)
end
...
end
Javaの場合パッケージ名も含めた本名でクラスを指定します。また、メソッドの引数と戻り値の型を表す文字列を指定する必要があり、整数はI、文字列はLjava/lang/String;などを(引数)戻り値
というフォーマットで渡します。省略した場合luajが引数を見て決めますが、Javaで定義されているシグネチャと違う場合エラーになるので明示する方が安全です。
コールバックもObjCとほぼ同じです。
public static void callbackLua(final String tipInfo,final int luaFunc){
Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFunc, "success");
Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFunc);
}
local function callbackLua(param)
if "success" == param then
print("java call back success")
end
end
local args = { "callbacklua", callbackLua }
local sigs = "(Ljava/lang/String;I)V"
local ok = luaj.callStaticMethod(className,"callbackLua",args,sigs)
if not ok then
print("call callback error")
end