如何实现Lua与C双向交互:调用Lua主函数及注册C函数
C与Lua交互实现方案
核心需求
- 在C代码中调用Lua脚本内的
main函数 - 将C语言的
LoadTBL函数注册到Lua环境,供Lua脚本调用
一、适配C函数为Lua可调用接口并注册
Lua仅支持调用符合lua_CFunction签名的函数,因此需要先将C语言的LoadTBL封装成Lua兼容的接口,再注册到Lua全局环境。
修改后的C代码
#include <stdio.h> #include <lua.h> #include <lauxlib.h> #include <lualib.h> // 原业务逻辑函数 int LoadTBL (int val1, int val2, int val3) { // 此处编写你的业务逻辑,示例返回0表示成功,非0表示失败 return 0; } // 封装为Lua可调用的接口函数 static int lua_LoadTBL(lua_State *L) { // 从Lua栈读取传入的3个整数参数 int val1 = luaL_checkinteger(L, 1); int val2 = luaL_checkinteger(L, 2); int val3 = luaL_checkinteger(L, 3); // 调用原C函数 int ret = LoadTBL(val1, val2, val3); // 向Lua栈压入返回结果和消息 if (ret == 0) { lua_pushboolean(L, 1); // 成功返回true lua_pushstring(L, "执行成功"); } else { lua_pushboolean(L, 0); // 失败返回false lua_pushstring(L, "参数无效或执行出错"); } // 返回值数量:2个(布尔结果+消息字符串) return 2; } void read_test(void) { lua_State *L; L = luaL_newstate(); luaL_openlibs(L); // 将封装后的函数注册到Lua全局环境,Lua中可直接调用LoadTBL lua_register(L, "LoadTBL", lua_LoadTBL); // 加载并执行Lua脚本(此时脚本已能访问LoadTBL函数) if (luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)) { printf("处理test.lua出错:%s\n", lua_tostring(L, -1)); lua_close(L); return; } // 调用Lua中的main函数 lua_getglobal(L, "main"); // 将main函数压入Lua栈 // 调用main函数:无传入参数,期望2个返回值,0表示无错误处理函数 if (lua_pcall(L, 0, 2, 0)) { printf("调用main函数出错:%s\n", lua_tostring(L, -1)); lua_close(L); return; } // 读取main函数的返回结果 int result = lua_toboolean(L, -2); // 第一个返回值(栈索引-2) const char *msg = lua_tostring(L, -1); // 第二个返回值(栈索引-1) printf("main执行结果:%s,消息:%s\n", result ? "成功" : "失败", msg); lua_close(L); printf("交互完成.\n"); } int main() { read_test(); return 0; }
二、调整Lua脚本适配交互逻辑
原Lua脚本中的Init/End未定义,需改为有效类型(如字符串或整数),同时修正参数索引(原代码中value[1]为非整数,不符合C函数参数要求):
修改后的Lua代码(test.lua)
-- 定义测试表格,将Init/End改为字符串常量,参数取value[2]-value[4] TBL = { { "Init", 0, 15, 0 }, { "End", 1, 16, 0 } } function main() for key, value in pairs(TBL) do -- 调用C注册的LoadTBL函数,传入后三个整数参数 local result, msg = LoadTBL(value[2], value[3], value[4]); if not result then return false, msg; end end return true, "success"; end
关键逻辑说明
- C函数注册:通过
lua_register将封装后的lua_LoadTBL绑定到Lua全局变量LoadTBL,Lua脚本即可直接调用。 - Lua函数调用:C代码通过
lua_getglobal获取Lua的main函数,再用lua_pcall执行,最后从Lua栈中读取返回值。 - 栈操作规则:Lua与C交互依赖栈传递参数和返回值,必须严格遵循栈的操作顺序(如参数入栈顺序、返回值出栈顺序)。
内容的提问来源于stack exchange,提问作者alberto silva
相关产品推荐
相关产品推荐

