首页 > 代码库 > c++回调lua的几种方式

c++回调lua的几种方式

第一种,通过函数名查找,每次都要查效率偏低

//全局表中找到函数
luaL_getglobal(L, "OnTimer");
//调用 lua_call(...);

 

第二种,c++提供接口由脚本注册回调函数,需要管理lua_ref的生命周期,管理不妥会有内存泄露

//c++提供lua接口,接受传递过来的lua函数
int
addTimer(lua_state* L) { int delay = lua_tonumer(L); int callback = luaL_ref(L, LUA_REGISTRYINDEX); //将lua函数存起来 addTimer(delay, callback); return 0; }

void onTimer(lua_state* L, int callback)
{
  lua_rawgeti( L , LUA_REGISTRYINDEX , callback );
  lua_call(...);
  //使用完毕需要将lua函数释放,否则会有内存泄露
  luaL_unref(callback);
}
--脚本将回调函数传递给c++
function
addTimer(delay, callback) CPP_INTERFACE.addTimer(delay, callback) end

 

第三种,lua提供一个静态函数给c++多次使用,lua函数只保存在lua中,依靠调用流水号(sn)与c++关联调用

int regTimerCallback(lua_state* L)
{
  //由lua提供一个统一的回调函数并且保存起来,程序运行期间不销毁
  refOnTimerCallback = luaL_ref(L,
LUA_REGISTRYINDEX);
  return 0;
}

int addTimer(lua_state* L)
{
  int delay = lua_tonumber(L);
  Timer* tm = new Timer();
  tm->sn = ++Timer.nextSN;
  tm->delay = delay;
  addTimer(tm);
  //将timer sn返回给lua
  lua_pushnumber(L, tm->sn);
  return 1;
}

void onTimer(lua_state* L, int sn)
{
  lua_rawgeti( L , LUA_REGISTRYINDEX , 
refOnTimerCallback);
  lua_pushnumber(L, sn);
  lua_call(...);
}
timers = {}

function addTimer(delay, callback)
    local sn = CPP_INTERFACE.addTimer(delay)
  timers[sn] = callback
end function onTimerMsg(sn)
  local callback = timers[sn]
  timers[sn] = nil
  if callback then
    callback()
  end
end CPP_INTERFACE.regTimerCallback(onTimerMsg)