C中调用LUA回调(LUA注册表)

时间:2022-09-01 16:28:03

实现原理:

通过将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&period;net中通过注册表来检测是否安装Office(迅雷&sol;QQ是否已安装&rpar;

    原文  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. AWVS漏洞测试-01节-AWVS的主要作用

    AWVS漏洞工具简单介绍 AWVS全称: Acunetix Web Vulnerability Scanner 中文翻译就是:Acunetix网站攻击扫描器 扫描网站漏洞,通过网络爬虫Crawler的 ...

  2. LR中获取当前系统时间方法

    方法一:使用loadrunner的参数化获取当前时间使用lr的参数化,非常方便,对lr熟悉的各位朋友也能马上上手,时间格式也有很多,可以*选择.步骤:1.将复制给aa的值参数化2.选中abc,使用右 ...

  3. Eclipse下使用Ant 【转】

    官方在线帮助文档:http://ant.apache.org/manual/index.html 中文汉化 帮助文档:http://www.cnblogs.com/pengxl/archive/201 ...

  4. HDU 2870 Largest Submatrix

    这三道题的关系是这样的,1505是1506的加强版,2870又是1505的加强版 如果按照上面由简到易的顺序来做的话,还是很简单的 这道题的思想就是 枚举+DP 因为某些字符可以变值,所以我们枚举a, ...

  5. Database事件研究

    1.Database.ObjectAppended.ObjectModified.ObjectErased事件 此事件如果不是Transaction提交而触发的,那么可以在事件内部使用Transact ...

  6. Oracle DECODE函数的语法介绍

    Oracle DECODE函数功能很强,下面就为您详细介绍Oracle DECODE函数的用法,希望可以让您对Oracle DECODE函数有更多的了解. Oracle DECODE函数 Oracle ...

  7. 【CSS】Intermediate6&colon;Display

    1display :inline/block/none 2.inline value Cause all list items in a list to appear next to each oth ...

  8. c语言结构体3之结构体嵌套

    注意: 1结构体内部再次定义一个结构体 但是没有创建结构体的实例  也就是说再次定义的结构体内部的变量会被当做母结构体的成员变量 struct tianchao { int data; ]; stru ...

  9. 如何增强ArcGIS插值图出图效果

    如何增强ArcGIS插值图出图效果 by 李远祥 在一些科研领域,经常会遇到使用插值的方式进行处理,并生成最终的插值图.插值图在ArcGIS里面非常容易生成,只要具备了采用点数据,通过ArcToolB ...

  10. 如何让linux的history命令显示时间记录

    在.bashrc文件追加如下内容即可: HISTFILESIZE= HISTSIZE= HISTTIMEFORMAT='%F %T ' export HISTTIMEFORMAT