cocos2d-x 2.2.0 如何在lua中注册回调函数给C++

cocos2d-x 2.2.0 如何在lua中注册回调函数给C++,第1张

概述cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件。 翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做。 值得吐槽的是,这套流程在开发中几乎是不可避免的,而cocos2d-x竟然不把它作为一个公用接口暴露给开发者,而需要我自己动手,真是无奈。 下面以一个简单的消息分发类为例子,演示如何完成这一工作。 Mes

cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件。
翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做。
值得吐槽的是,这套流程在开发中几乎是不可避免的,而cocos2d-x竟然不把它作为一个公用接口暴露给开发者,而需要我自己动手,真是无奈。


下面以一个简单的消息分发类为例子,演示如何完成这一工作。

Messagedispatcher.h
class Messagedispather { public: static Messagedispather* shareddispather(); public: voID invokeLuaCallbackFunction(int msgid,const char* text); voID registerScriptHandler(int nHandler); private: int mLuaHandlerID; }; 
Messagedispatcher.cpp
#include "ccluaEngine.h" Messagedispather* shareddispather() { static Messagedispather* instance = NulL; if(instance == NulL) instance = new Messagedispather(); return instance; } voID Messagedispather::invokeLuaCallbackFunction(int msgid,const char* text) { if(mScriptHandler > 0) { ccluaStack* stack = ccluaEngine::defaultEngine()->getLuaStack(); stack->pushInt(msgid); stack->pushString(text); stack->executeFunctionByHandler(mScriptHandler,2); stack->clean(); } } voID Messagedispather::registerScriptHandler(int nHandler) { mLuaHandlerID = nHandler; } 
说明

#include "ccluaEngine.h"
这个头文件来自cocos2d-x\scripting\lua\cocos2dx_support
整个文件夹里的内容是cocos2d-x引擎做lua绑定时封装的一些工具类。
你需要在你的项目中添加这个目录的include搜索路径。

voID registerScriptHandler(int nHandler)
这个函数需要暴露给lua。
在lua中调用这个函数,参数nHandler的位置传进去一个lua函数,就能够在C++这边得到一个nHandler的整数句柄值。
之后任何时间如果想要在C++中调用刚刚注册的lua回调函数,需要以这个整数值来指代那个函数。

voID invokeLuaCallbackFunction(int msgid,const char* text)
在C++用调用此函数,我们期待它会调用到一个在lua中定义的回调函数。
具体这个函数里的实现是什么意思,如果你对lua c API有一定了解的话应该很容易能看懂,我就不再做解释。

用于tolua的pkg文件
class Messagedispather { static Messagedispather* shareddispather(); voID registerScriptHandler(LUA_FUNCTION nHandler); }; 
在lua中使用Messagedispatcher
local function onMessage(msgid,text) print(msgid,text) end Messagedispatcher:shareddispatcher():registerScriptHandler(onMessage) 
万事大吉。。。。。才怪!

有没有发现我们的pkg文件中有一个类型是LUA_FUNCTION??
对,因为这个参数在lua中应该传入一个函数,而到了C++这边我们拿到的却是一个int。
这并不是tolua的缺省行为,而是cocos2d-x针对这种情况做的一个特殊处理。
翻看cocos2d-x的tolua绑定流程,我们可以发现build.bat中的内容是这样的:
tolua++ -L basic.lua -o "../../scripting/lua/cocos2dx_support/LuaCocos2d.cpp" Cocos2d.pkg
这里basic.lua是一些额外的逻辑,其中处理LUA_FUNCTION类型的逻辑也在里面。

那么我们可以照猫画虎,请创建这样一个lua文件:

_is_functions = _is_functions or {} _to_functions = _to_functions or {} @H_404_147@-- register LUA_FUNCTION,LUA_table,LUA_HANDLE type _to_functions["LUA_FUNCTION"] = "toluafix_ref_function" _is_functions["LUA_FUNCTION"] = "toluafix_isfunction" _to_functions["LUA_table"] = "toluafix_totable" _is_functions["LUA_table"] = "toluafix_istable" local toWrite = {} local currentString = '' local out local WRITE,OUTPUT = write,output function output(s) out = _OUTPUT output = OUTPUT @H_404_147@-- restore output(s) end function write(a) if out == _OUTPUT then currentString = currentString .. a if string.sub(currentString,-1) == '\n' then toWrite[#toWrite+1] = currentString currentString = '' end else WRITE(a) end end function post_output_hook(package) local result = table.concat(toWrite) local function replace(pattern,replacement) local k = 0 local nxt,currentString = 1,'' repeat local s,e = string.find(result,pattern,nxt,true) if e then currentString = currentString .. string.sub(result,s-1) .. replacement nxt = e + 1 k = k + 1 end until not e result = currentString..string.sub(result,nxt) if k == 0 then print('Pattern not replaced',pattern) end end replace([[*((LUA_FUNCTION*)]],[[(]]) replace([[tolua_usertype(tolua_S,"LUA_FUNCTION");]],[[]]) WRITE(result) end 

然后在你执行tolua++的时候把这个文件作为-L参数传进去就可以了。


到这里,应该就可以正常生成了。

当时我遇到了运行时出现错误的情况。

修改成这样就没有问题了

LUA_FUNCTION luaCallback = toluafix_ref_function(tolua_S,2,0);

主要是自动生成的回调函数等号右边会出现强制类型转换,但是这样就会报错

把这个去掉就可以了。

总结

以上是内存溢出为你收集整理的cocos2d-x 2.2.0 如何在lua中注册回调函数给C++全部内容,希望文章能够帮你解决cocos2d-x 2.2.0 如何在lua中注册回调函数给C++所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1017828.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存