网上早已流传着cocos2dx引擎自带的lua-binding的方法。之前我自己尝试了一遍,发现一直不顺利,又不想去看python代码,所以在这里采用了更加便捷的方式。
编写.h以及.cpp代码
- 打开frameworks/runtime-src/proj.win32/projname.sln以打开你的工程
- 定位到以下地方(或者随便别的地方,记住路径即可),编写你自己的代码。
首先看一下.h文件
#ifndef __JAVA_LUA_BRIDGE_TOOLKIT_H__
#define __JAVA_LUA_BRIDGE_TOOLKIT_H__
#include <string>
#include "cocos2d.h"
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif
TOLUA_API int register_javaLuaBridgeToolkit(lua_State* L);
#endif
- 需要include几个lua的头文件,注意需要用extern “c”关键字,表示用c这种编译方式编译其中的内容,避免link的时候出错。
- #include “cocos2d.h”是为了我在代码里面可以使用CCLOG函数。
接下来看cpp文件:
#include "JavaLuaBridgeToolkit.h"
int sayHello(lua_State *L){
string msgFromLua = luaL_checkstring(L, 1);
CCLOG("Hello~ from c++, msg from lua: %s", msgFromLua.c_str());
lua_pushstring(L, "Hello World From C++");
return 1;
}
static const struct luaL_Reg myLib[] =
{
{ "sayHello", sayHello },
{ NULL, NULL }
};
int register_javaLuaBridgeToolkit(lua_State* L) {
luaL_register(L, "JavaLuaBridge", myLib);
return 1;
}
lua和c++交互的相关知识,见这里Lua和C++交互详细总结
做了几件事:
1. 写了一个sayHello函数,参数是lua_state,可以用来访问一个lua栈。在这个函数里从lua取出来一个string变量,CCLOG出来之后,把一个string变量重新放到栈顶。return的int值是lua那边要拿到的返回值个数。
2. 创建一个struct,用以注册sayHello方法,注意最后要加一个{ NULL, NULL }以表示结束。
3. 使用luaL_register函数来注册这个sayHello到lua,第二个参数是lua那边要调用的全局变量名。
问题:谁来调用register_javaLuaBridgeToolkit()函数呢?
查看了别的register方法,发现在AppDelegate.cpp的applicationDidFinishLaunching()函数里有这样一段代码:
点进去一看,跳转到lua_module_register.h文件。然后我们往lua_module_register函数里调用register_javaLuaBridgeToolkit(),并在最上面引用头文件。
到这一步,我们已经可以成功的在win平台build成功了,build完可以在游戏的main.lua添加以下语句:
local ret = JavaLuaBridge.sayHello("msg from lua");
print(ret);
运行可以看到输出结果。
至此,windows这边已经没有问题了。
然后我又尝试打出一个apk包。打apk包的过程中遇到了问题,说是cannot find reference。网上搜索之后,解决方法是:
找到frameworks/cocos2d-x/cocos/scripting/lua-bindings/proj.android/android.mk并添加以下语句,以声明源文件和头文件:
#java lua bridge
LOCAL_SRC_FILES += ../manual/bridge/JavaLuaBridgeToolkit.cpp \
LOCAL_C_INCLUDES := //省略
$(LOCAL_PATH)/../manual/bridge \
现在点击生成apk,可以成功生成了。