实现原理:

通过将LUA中得回调函数存入LUA注册表中来保存LUA函数,然后在需要回调时从LUA注册表中取出LUA函数进行调用

下面是一些预备知识:(学习两个重要的函数)

原汁原味的英文解释的最透彻,翻译的话就会加入自己的理解


LUA_GLOBALSINDEX
LUA_ENVIRONINDEX
LUA_REGISTRYINDEX
Lua provides a registry, a pre-defined table that can be used by any C code to store whatever Lua value it needs to store. This table is always located at pseudo-index LUA_REGISTRYINDEX. Any C library can store data into this table, but it should take care to choose keys different from those used by other libraries, to avoid collisions. Typically, you should use as key a string containing your library name or a light userdata with the address of a C object in your code
 

int luaL_ref (lua_State *L, int t);

Creates and returns a reference, in the table at index t, for the object at the top of the stack (and pops the object).

A reference is a unique integer key. As long as you do not manually add integer keys into table tluaL_ref ensures the uniqueness of the key it returns. You can retrieve an object referred by reference r by calling lua_rawgeti(L, t, r). Function luaL_unref frees a reference and its associated object.

If the object at the top of the stack is nilluaL_ref returns the constant LUA_REFNIL. The constant LUA_NOREF is guaranteed to be different from any reference returned by luaL_ref.


void luaL_unref (lua_State *L, int t, int ref);

Releases reference ref from the table at index t (see luaL_ref). The entry is removed from the table, so that the referred object can be collected. The reference ref is also freed to be used again.

If ref is LUA_NOREF or LUA_REFNILluaL_unref does nothing.

这样使用

将lua函数保存到这个注册表。lua提供了在表里增加一个条目的API,luaL_ref,返回值是新条目的key,一个整数。
int handler = luaL_ref( L , LUA_REGISTRYINDEX );
下面是简化后的代码,是保存lua中传入的一个function,并将其作为回掉函数调用
代码如下:
 int Test_callback(lua_State* luaState)
{
int topindex = lua_gettop(luaState);
assert(topindex == );
/** check stack top is lua function */
if (!lua_isfunction(luaState, topindex))
generate_error(luaState, "param #1 is not function\n"); /** register lua function to register table and we can use with func id
luaL_ref will pops the stack top */
int luafuncid = luaL_ref(luaState, LUA_REGISTRYINDEX); { /** Wait a moment */
/** get function by ref id */
lua_rawgeti(luaState, LUA_REGISTRYINDEX, luafuncid);
if (!lua_isfunction(luaState, -))
generate_error(luaState, "callback is not a lua function\n"); /** push params */ /** call lua function */
if (lua_pcall(luaState, , , ) != ) {
/** error message on the stack top, lua_error will jump */
lua_error(luaState);
}
luaL_unref(luaState, LUA_REGISTRYINDEX, luafuncid);
}
return ; } extern int luaopen_Test_luabinding(lua_State* luaState)
{
static const struct luaL_Reg funcs[] = {
{"callback", Test_callback},
{NULL, NULL}
};
luaL_register(luaState, "test", funcs);
return ;
}
 
 

C中调用LUA回调(LUA注册表)的更多相关文章

  1. 最原始的COM组件调用过程(不使用注册表信息)

    最原始的COM组件调用过程(不使用注册表信息) 最近因为项目的关系开始研究COM组件了,以前都认为COM过时了,所以也没怎么接触. 现在好好补补课了. 一般调用COM都是通过注册表找到它的位置, 然后 ...

  2. Win64 驱动内核编程-15.回调监控注册表

    回调监控注册表 在 WIN32 平台上,监控注册表的手段通常是 SSDT HOOK.不过用 SSDT HOOK 的方式监控注册表实在是太麻烦了,要 HOOK 一大堆函数,还要处理一些 NT6 系统有而 ...

  3. 注册表的作用、bat文件中REG ADD命令添加注册表项以及bat

    注册表的用途与设置 注册表是windows的核心,里面储存着大量的系统信息,说白了就是一个庞大的数据库.如果你不懂什么是数据库,那没关系,不影响你了解注册表,不过最好对数据库有所了解.注册表里面所有的 ...

  4. ASP.NET中如何读取和写入注册表

    直接给源码: 读取注册表内容: RegistryKey regkey=Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Window ...

  5. 将gbk字符串转换成utf-8,存储到注册表中后,再次从注册表读取转换成gbk,有问题!!!

    char *a = "新2新"; printf("gbk:'%s'\n", a); int ii; ; ii < strlen(a); ii++) { p ...

  6. 入侵检测中需要监控的注册表路径研究(Windows Registry Security Check)

    1. Windows注册表简介 注册表(Registry,繁体中文版Windows称之为登录档)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息.早在Wind ...

  7. asp.net中通过注册表来检测是否安装Office(迅雷/QQ是否已安装)

    原文  asp.net中通过注册表来检测是否安装Office(迅雷/QQ是否已安装) 检测Office是否安装以及获取安装 路径 及安装版本  代码如下 复制代码 #region 检测Office是否 ...

  8. NSIS:在注册表中记录安装路径以便重装或升级时读取

    原文 NSIS:在注册表中记录安装路径以便重装或升级时读取 在NSIS中,这个功能是非常有用的,可以避免用户把程序安装到多个位置的尴尬. 第1步:在“安装目录选择页面”前面加入以下代码: 1 !def ...

  9. Django框架(九)—— 单表增删改查,在Python脚本中调用Django环境

    目录 单表增删改查,在Python脚本中调用Django环境 一.数据库连接配置 二.orm创建表和字段 三.单表增删改查 1.增加数据 2.删除数据 3.修改数据 4.查询数据 四.在Python脚 ...

  10. inno setup读取注册表遇到的一个坑

    一.背景 目前,公司针对PR开发的一个插件需要发布到64位系统上.该插件包括一个prm格式的文件和若干个DLL文件.其中,prm文件需要复制到PR公共插件目录下,DLL需要复制到Windows系统目录 ...

随机推荐

  1. xml基础学习笔记02

    接着上次的xml笔记01 ,记录一下如何DOM创建xml 一.由于没有特意来写博客,都是在程序中用注释的方法记录笔记,整理过来难免格式错误,排版什么的,大家好事看不懂就仔细看给出的代码加上注释,一定会 ...

  2. public、protect、private在父类子类中使用

    先贴出一张,直观的.估计大家都见过的关于public.protect.private的范围图 作用域 当前类 同一package 子孙类 其他package public     T         ...

  3. 【CentOS 6.5】 U盘安装以及桌面空白问题

    在研华ARK-5260上安装CentOS 6.5 下载CentOS-6.5-x86_64-bin-DVD1.iso 附上百度网盘下载地址:http://pan.baidu.com/s/1eQf1Eeu ...

  4. 19、android面试题整理(自己给自己充充电吧)

    (转载,出处丢失,请原作者原谅,如有意见,私信我我会尽快删除本文) JAVA 1.GC是什么? 为什么要有GC?GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问 ...

  5. 第六周博客技术发表 C语言代码

    #include <stdio.h>       /*使用printf要包含的头文件*/#include <conio.h>void main(void)        /*主 ...

  6. hibernate--OneToOne

    一对一(one to one) 单向关联映射 两个对象是一对一的的关系. 有两种策略可以实现一对一的关联映射 l  主键关联:即让两个对象具有相同的主键值,以表明他们之间的一对一的对应关系;数据库表不 ...

  7. redis.conf配置

    # Redis configuration file example # Redis示例配置文件 # Note on units: when memory size is needed, it is ...

  8. JSP Workshop

    http://www.cnblogs.com/ITtangtang/p/4126395.html 发现http://www.tutorialspoint.com/里的资料很全也很不错啊! 资料:htt ...

  9. python实现web分页日志查看

    当我们维护一个网站时,无论前台还是后台,经常会出现各种个样的问题.有时候问题很难直观的发现,这个时候只能查看各种日志来跟踪问题.但是查看日志有各种个样的问题.首先,要用各种工具登陆到服务器,这个有时候 ...

  10. 小试牛刀MVC简单网页

    上次我们创建了第一个MVC的网站,没用下,这次就简单来运行下,首先大家要去理解下MVC模式到底什么关系.在这里我就不多说,直接创建一个网页,用来显示一些数据,数据库的话我就先简单用这样创建先,为了方便 ...