实现原理:

通过将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. Mac下的常用Shell命令

    今天介绍一下在Mac的终端中一些常用的Shell命令: 1.查看当前工作目录的完整路径 pwd (pwd的原意是:print work directiory,而不是密码password的意思,呵呵) ...

  2. liferay7中如何Hiding the default Success Message

    下面介绍如何把在Liferay 7中如何把action执行成功之后的信息不显示,因为宝宝有需要,就去查了相关源码和资料. 如果想要某个portlet不显示执行成功的信息,在doProcessActio ...

  3. SQL Server性能优化(5)表设计时的注意事项

    一. 是否需要冗余列 现在一些项目的数据库设计中,为了提高查询速度,把基本表的一些列也放到了数据表里,导致数据冗余.例如在热表的数据库里,原始数据表Measure_Heat里加了如房间号,单元号,楼号 ...

  4. CSS水平导航条和纵向导航条

    问题描述:         使用CSS制作水平导航条和纵向导航条   问题解决:        (1)水平导航条            1.1 效果预览:                   1.2 ...

  5. jquery如何删除一个元素后面的所有元素

    $("div>span:first").nextAll().remove()

  6. 【BZOJ】【2084】【POI2010】Antisymmetry

    Manacher算法 啊……Manacher修改一下就好啦~蛮水的…… Manacher原本是找首尾相同的子串,即回文串,我们这里是要找对应位置不同的“反回文串”(反对称?233) 长度为奇数的肯定不 ...

  7. Leetcode#128 Longest Consecutive Sequence

    原题地址 1. 把所有元素都塞到集合里2. 遍历所有元素,对于每个元素,如果集合里没有,就算了,如果有的话,就向左向右拓展,找到最长的连续范围,同时在每次找的时候都把找到的删掉.这样做保证了同样的连续 ...

  8. poj 1185

    上一题的升级版 dp[i][j][k] 表示第 i 行状态为 k 第i-1行状态为 j #include <cstdio> #include <cstdlib> #includ ...

  9. O2O模式成功案例分享 汲取精华化为己用

    本文通过分享一些公司的o2o成功案例让您了解什么是O2O,o2o的优势,o2o模式有哪些,未来我们要如何做o2o才更有竞争力,学牛人的o2o创新玩法,摸索适合自己的o2o思路.拥抱o2o - 传统企业 ...

  10. CentOS 6下安装nginx

    原文:http://yubosun.akhtm.com/tech/centos-nginx.htm 1 在nginx官方网站下载一个rpm包,下载地址是:http://nginx.org/en/dow ...