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

收集整理的这篇文章主要介绍了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语言运用回调函数实现计算器
  • C语言回调函数的简单运用
  • c语言中回调函数的使用以及实际作用详析
  • 关于c语言中回调函数的理解
  • 详解C语言编程中的函数指针以及函数回调
  • C语言中的回调函数实例
  • C语言中回调函数的使用详情