1. 程式人生 > >Lua知識點_高階_c++中呼叫Lua回撥函式

Lua知識點_高階_c++中呼叫Lua回撥函式

以下是在cocos2dx-3.10 lua中


1.概述
以下主要用於lua中執行了c++函式,在c++函式執行完成後,呼叫Lua的回撥函式。
注意:若c++中使用了多執行緒,這裡的這種呼叫Lua的方法會有一定機率導致程式崩潰,因為Lua不支援多執行緒,
  替代的方法是在Lua的update函式中每隔一定時間就呼叫c++函式獲得相關資料。

2.例項
frameworks
  --runtime-src
    --Classes
      --test.cpp
 --RegisterToLua.cpp
src--
--main.lua
--app
  --views
    --CallbackTable.lua
--hello.lua


(1)建立儲存回撥函式的全域性表
CallbackTable.lua———
CallbackTable = {}
--以Lua函式名字作為key的表,此表的obj元素是一個儲存當前指令碼this物件、以及最後執行的處理函式的表
CallbackTable.keys = {}
--新增監聽
--obj  儲存當前指令碼this物件
--fun  最後執行的處理函式
--key  在c++中呼叫的Lua函式
function CallbackTable:listen(obj,fun,key)
    if self.keys[key] == nil then
    self.keys[key] = {}
    end
    self.keys[key][obj] = {obj=obj,fun=fun}
end
--解除監聽,按傳入的指令碼this物件
function CallbackTable:unListenByObj(obj)
    for key, var in pairs(self.keys) do
    var[obj] = nil
    end
end
--解除監聽,按傳入的在c++中呼叫的Lua函式名字
function CallbackTable:unListenByKey(key)
    self.keys[key] = nil
end
--解除監聽,按傳入的指令碼this物件、在c++中呼叫的Lua函式名字
function CallbackTable:unListen(obj,key)
    if self.keys[key] == nil then
        return
    end
    self.keys[key][obj] = nil
end
--呼叫最後執行的處理函式
function CallbackTable:notify(key,data)
    if self.keys[key] == nil then
        return
    end
    for k,o in pairs(self.keys[key]) do
        o.fun(o.obj,key,data)
    end
end


(2)建立Lua測試指令碼
hello.lua———
require "app.views.CallbackTable"
local test = class("test", cc.load("mvc").ViewBase)


function test:onCreate()
    self:registerScriptHandler(function(state)
        if state == "enter" then
            self:onEnter()
        elseif state == "exit" then
            self:onExit()
        end
    end)
end


function test:onEnter()
CallbackTable:listen(self,function(obj,key,index) self:showTestUI() end,"testCompled")
end


function test:onExit()
    CallbackTable:unListenByObj(self)
    self:unregisterScriptHandler()--取消自身監聽
end


function test:showTestUI(filename)
    release_print("showTestUI")
--這裡呼叫c++函式(其中會呼叫 onTestCompled)
cpp_test()
end


--在c++中呼叫的Lua函式(注意:這裡函式名字前面沒有新增test:,是一個全域性函式)
function onTestCompled()
    release_print("testCompled")
    CallbackTable:notify("testCompled",nil)
end


(3)在c++中呼叫Lua的函式
RegisterToLua.cpp------
--這裡的類用於註冊c++函式到Lua
...
void RegisterToLua::bind(lua_State *ls)
{
lua_register(ls, "cpp_test", cpp_test);
}
int RegisterToLua::cpp_test(lua_State* ls){
    const char* str = lua_tostring(ls, 1);
    printf("%s\n",str);
testCallback();


    return 0;
}
//回撥函式
void RegisterToLua::testCallback(){
    lua_State* L = cocos2d::LuaEngine::getInstance()->getLuaStack()->getLuaState();
    lua_getglobal(L, "onTestCompled");
    lua_call(L, 0, 0);


    return 0;
}