C语言模块回调Lua函数的两种方法
lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平衡稍微会多写一点代码。 今天分享学到的C模块回调Lua函数的两种方法,都是炒冷饭,大侠勿喷。
1. C保存函数对象
C模块可以通过注册表保存Lua里面的对象,等适当时候取出再调用即可。
static int lua_callback = LUA_REFNIL;
static int setnotify(lua_State *L)
{
lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
static int testnotify(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
lua_call(L, 0, 0);
}
luaL_ref把栈顶的值取出,放到指定的tabel中,然后返回一个索引(目测是数组的index)。 lua_rawgeti把之前保存的function对象取出,再由lua_call调用。
复制代码 代码如下:
function callback( )
print "Callback"
end
cb.setnotify(callback)
cb.testnotify()
2. C访问Lua全局环境
第二种方法更简便,C直接调用Lua中的函数,就像Lua调用C一样
复制代码 代码如下:
static int testenv(lua_State *L)
{
lua_getglobal(L, "defcallback");
lua_call(L, 0, 0);
}
该方法的缺点就是如果C模块独立编写,方法名就不太灵活。 用这种方法一般会在Lua端再封装一层,以隔离全局环境。
3. 完整例子
cb.c
#include <stdio.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int lua_callback = LUA_REFNIL;
static int setnotify(lua_State *L)
{
lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
static int testnotify(lua_State *L)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
lua_call(L, 0, 0);
}
static int testenv(lua_State *L)
{
lua_getglobal(L, "defcallback");
lua_call(L, 0, 0);
}
static const luaL_Reg cblib[] = {
{"setnotify", setnotify},
{"testnotify", testnotify},
{"testenv", testenv},
{NULL, NULL}
};
int luaopen_cb(lua_State *L)
{
luaL_register(L, "cb", cblib);
return 1;
}
test.lua
复制代码 代码如下:
require("cb")
function callback( )
print "Callback"
end
function defcallback()
print "Predef callback"
end
cb.setnotify(callback)
cb.testnotify()
print "Done"
cb.testenv()
您可能感兴趣的文章:
- C模块回调Lua函数的两种方法
- C模块回调Lua函数的两种方法
- C模块回调Lua函数的两种方法
- 关于cocos2dx3.0 cpp回调lua函数新方法
- C语言支持的两种函数指针的调用方法
- CCScheduler(调度器 两种回调1、update回调(通过object的update函数实现所以每次调用) 2、一般回调(通过timer timer是可以设置fSeconds的可变调用间隔))
- 【C语言】用递归和循环两种方法实现单链表倒置
- os模块中关于文件/目录常用的函数使用方法
- python查看模块,对象的函数方法
- lua 函数回调技巧
- [转] 克服C语言gets函数缺陷的方法初探
- os、os.path模块中关于文件、目录常用的函数使用方法
- cocos2dx 3.3 + lua 学习笔记(04)--- 动作回调、函数回调、骨骼动画回调
- asp.net中执行exe应用程序2008-07-03 15:53在asp.net中执行应用程序有两种方法:1、调用win32函数ShellExecute。2、用.NET Framework中的Process类。下面我分别用这两种方法执行Windows中的
- javascript基础之两种函数的定义方法
- os, os.path模块中关于文件/目录常用的函数使用方法
- ThinkPHP自动完成中使用函数与回调方法实例
- 查看python的模块和函数帮助文档方法
- c语言:两种方法判断1到100之间的奇数
- python中使用sys模板和logging模块获取行号和函数名的方法