如何在C语言enter_server函数中调用Lua定义的Server函数
实现Lua与C的函数交互:持久化Lua函数并在C中触发执行
需求说明
Lua脚本中定义了包含Server函数的表tbl,C语言通过read_table读取该表后,需要把Server函数保存到C变量里,后续每次调用C的enter_server函数时,都能执行对应的Lua Server函数。
Lua 端脚本示例
-- 定义包含Server函数的全局表tbl tbl = { Server = function() print("Lua Server函数已执行!") -- 这里可以添加你的业务逻辑代码 end }
C 端实现代码
#include <lua.h> #include <lauxlib.h> #include <lualib.h> #include <stdio.h> // 存储Lua Server函数在注册表中的引用(初始值表示未注册) static int lua_server_func_ref = LUA_NOREF; // 读取Lua表,提取并保存其中的Server函数 void read_table(lua_State *L) { // 假设调用此函数时,栈顶是Lua中的tbl表 lua_getfield(L, -1, "Server"); // 从表中取出Server函数,压入栈顶 if (lua_isfunction(L, -1)) { // 将函数存入Lua注册表,获取并保存引用索引 lua_server_func_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { fprintf(stderr, "错误:tbl.Server不是一个函数\n"); lua_server_func_ref = LUA_NOREF; } lua_pop(L, 1); // 弹出栈顶的函数,恢复栈平衡 } // 触发执行保存的Lua Server函数 void enter_server(lua_State *L) { if (lua_server_func_ref != LUA_NOREF) { // 从注册表中取出之前保存的Lua函数,压入栈顶 lua_rawgeti(L, LUA_REGISTRYINDEX, lua_server_func_ref); // 调用Lua函数:0个参数,0个返回值,第三个参数0表示错误处理栈索引 if (lua_pcall(L, 0, 0, 0) != LUA_OK) { fprintf(stderr, "执行Lua Server函数出错:%s\n", lua_tostring(L, -1)); lua_pop(L, 1); // 弹出错误信息,恢复栈平衡 } } else { fprintf(stderr, "错误:Lua Server函数未注册\n"); } } // 示例主函数,演示完整流程 int main() { // 创建Lua虚拟机实例 lua_State *L = luaL_newstate(); luaL_openlibs(L); // 加载Lua标准库 // 加载并执行Lua脚本,定义tbl表 if (luaL_dofile(L, "your_script.lua") != LUA_OK) { fprintf(stderr, "加载Lua脚本出错:%s\n", lua_tostring(L, -1)); lua_close(L); return 1; } // 获取全局tbl表,压入栈顶 lua_getglobal(L, "tbl"); if (lua_istable(L, -1)) { read_table(L); } else { fprintf(stderr, "错误:tbl不是一个表\n"); } lua_pop(L, 1); // 弹出tbl表,恢复栈平衡 // 模拟两次调用enter_server,触发Lua函数执行 enter_server(L); enter_server(L); // 释放注册表中的函数引用,避免内存泄漏 if (lua_server_func_ref != LUA_NOREF) { luaL_unref(L, LUA_REGISTRYINDEX, lua_server_func_ref); lua_server_func_ref = LUA_NOREF; } lua_close(L); // 关闭Lua虚拟机 return 0; }
核心逻辑说明
- 函数持久化:用
luaL_ref把Lua函数存入Lua注册表,这样函数不会被垃圾回收器清理,同时用C变量保存引用索引,方便后续快速取用。 - 安全调用:使用
lua_pcall调用Lua函数,能捕获并处理调用过程中的错误(比如函数内部抛出异常),避免C程序崩溃。 - 栈平衡:每次操作Lua栈后,都及时弹出不需要的元素,保证栈的状态始终可控,避免栈溢出或逻辑混乱。
内容的提问来源于stack exchange,提问作者alberto silva
相关产品推荐
相关产品推荐

