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)

c++回调lua的几种方式

时间: 2024-11-09 09:20:22

c++回调lua的几种方式的相关文章

C++中实现回调机制的几种方式(一共三种方法,另加三种)

(1)Callback方式Callback的本质是设置一个函数指针进去,然后在需要需要触发某个事件时调用该方法, 比如Windows的窗口消息处理函数就是这种类型. 比如下面的示例代码,我们在Download完成时需要触发一个通知外面的事件: typedef void (__stdcall *DownloadCallback)(const char* pURL, bool bOK);void DownloadFile(const char* pURL, DownloadCallback call

android回调接口的两种方式

熟悉MS-Windows和X Windows事件驱动设计模式的开发人员,通常是把一个方法的指针传递给事件源,当某一事件发生时来调用这个方法(也称为“回调”).Java的面向对象的模型目前不支持方法指针,似乎不能使用这种方便的机制. 但是java本身拥有interface,我们可以用interface实现相同的效果.在android中,如果我们需要对一个button的点击事件往外传,可以有两种实现方式. 第一种方式的大体步骤是: 1.定义一个回调接口,用来捕捉和“存放”点击事件. public i

[转]C/C++实现回调机制的几种方式(回调、槽、代理)

转自:https://www.jianshu.com/p/4f907bba6d5f (1)Callback方式(回调) Callback的本质是设置一个函数指针进去,然后在需要需要触发某个事件时调用该方法, 比如Windows的窗口消息处理函数就是这种类型.比如下面的示例代码,我们在Download完成时需要触发一个通知外面的事件: #include <iostream> typedef void (__stdcall *DownloadCallback)(const char *pURL,b

lua中遍历table的几种方式比较

在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtest) do XXX end for key, value in ipairs(tbtest) do XXX end for i=1, #(tbtest) do XXX end for i=1, table.maxn(tbtest) do XXX end 前两种是泛型遍历,后两种是数值型遍历.当然你还会说

十四、Android学习笔记_Android回调函数触发的几种方式 广播 静态对象

一.通过广播方式: 1.比如登录.假如下面这个方法是外界调用的,那么怎样在LoginActivity里面执行登录操作,成功之后在回调listener接口呢?如果是平常的类,可以通过构造函数将监听类对象传入即可.但是在Activity中不能传递监听对象,所以考虑使用广播来实现. public void login(final LoginOnClickListener listener) { Intent intent = new Intent(context, LoginActivity.clas

cocos2d-x的lua脚本加载CocostudioUI两种方式

前言 当前版本使用的是quick cocos2dx lua 3.3.UI使用cocostudio编辑器.我们在程序里面可以使用两种方式进行解析UI.开始的时候用的是quick的方法,结果遇到了坑(百分比控件布局,你们可以自己试一下什么效果). 我在后面简单提一下,不过不是自己遇到的坑,就不知道有多坑. 一.quick使用cocostudio 1.加载 local uiNode = cc.uiloader:load("TestUI.json") self:addChild(uiNode)

异步回调函数-创建进程的三种方式

回调函数 有两个类,A,B,在类A中调用B,在B中调用A的方法完成A的工作,那么这个在B类中调用的A的函数就称为回调函数. 异步回掉函数:类A将自己的工作交给类B后,继续执行剩下的程序,而B继续完成A交给的工作. 使用方法: 1.定义一个接口 2.A可以直接继承此接口,也可以定义一个内部类继承此接口: 定义一个方法,调用B中的方法 3.B中的方法调用A中的方法. //定义接口 public interface doJob { public void fillBlank(int a,int b,i

ngx lua获取时间戳的几种方式

原创自由de单车 最后发布于2017-02-14 14:58:43 阅读数 18218 收藏 在ngx_lua里,获取时间相关信息的方式大概有4种(见下面代码): print(string.format("%s, %s, %s, %s", ngx.time(), os.time(), os.clock(), ngx.now()))ngx.exit(200) -- 以上代码会输出:1486971340, 1486971340, 209.77, 1486971340.422 可见,通过os

scrapy采集列表页的另一种方式

又是采集绿色下载站的最新软件,又是采用另一种方式(前两种是采用正则和xpath),呵呵 感觉有点像孔乙已的茴字有几种写法了 这回用CrawlSpider,Rule来配合采集 这次不用生成许多start_urls列表项了,可以按规则来自动读取,贴核心代码 # -*- coding: utf-8 -*- from scrapy.contrib.spiders import CrawlSpider,Rule from scrapy.selector import Selector from scrap