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()
下一篇: vivox60怎么样修改悬浮球皮肤样式?
推荐阅读
-
pow函数(数学次方)在c语言的用法,两种编写方法实例( 计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值)
-
详解C#中通过委托来实现回调函数功能的方法
-
C语言模块回调Lua函数的两种方法
-
Lua中让回调函数支持回调对象方法的解决方法
-
C语言工作笔记-对函数指针的进一步认识(与回调函数结合使用,并且对比C++的回调)
-
pow函数(数学次方)在c语言的用法,两种编写方法实例( 计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值)
-
c语言中回调函数的使用以及实际作用详析
-
详解C#中通过委托来实现回调函数功能的方法
-
C语言模块回调Lua函数的两种方法
-
Lua中让回调函数支持回调对象方法的解决方法