首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

C模块回调Lua函数的两种步骤

2013-11-09 
C模块回调Lua函数的两种方法作者:ani_di版权所有,转载务必保留此链接 http://blog.csdn.net/ani_diC模块回

C模块回调Lua函数的两种方法

作者:ani_di
版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di

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"endcb.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"endfunction defcallback()  print "Predef callback"endcb.setnotify(callback)cb.testnotify()print "Done"cb.testenv()

热点排行