如何确保C语言调用的是指定的Lua函数
在一个Lua脚本中,存在两个函数分别是mainFunction
和callbackFunction
,其中callbackFunction
作为参数传递给mainFunction
,那么在C语言中如何确保lua_pcall
调用的是mainFunction
而非callbackFunction
呢?
C语言调用Lua脚本函数
C和Lua之间进行通信的桥梁是lua_State
中的堆栈,参数传递也是用堆栈来进行。
C语言调用Lua函数的接口是lua_pcall
,其函数定义如下所示:
int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc);
其中nargs
是传入的参数个数,nresults
是接收的返回值个数,errfunc
是错误处理函数。
由于是通过堆栈传递数据,因此需要将函数名和参数都先压入堆栈才可以,并且需要确保最后一个参数位于栈顶。
如何确定调用的函数?
之前有一个疑惑的地方在于,如果一个Lua函数的参数是另一个函数,那么lua_pcall
是怎么识别出执行的是哪个函数呢?
形如:
-- 定义回调函数
function callbackFunction()
print("Callback function called")
end
-- 定义主函数,接受一个回调函数作为参数
function mainFunction(callback)
print("Main function called")
callback()
end
在C语言中调用mainFunction
函数的方法如下所示:
#include <lua5.3/lauxlib.h>
#include <lua5.3/lua.h>
#include <lua5.3/lualib.h>
#include <stdio.h>
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// 加载并执行Lua脚本
if (luaL_loadfile(L, "lua_c_callfunction.lua") || lua_pcall(L, 0, 0, 0))
{
fprintf(stderr, "Cannot run Lua file: %s\n", lua_tostring(L, -1));
return 1;
}
// 获取主函数 mainFunction
lua_getglobal(L, "mainFunction");
// 获取回调函数 callbackFunction 并压入堆栈
lua_getglobal(L, "callbackFunction");
// 调用 mainFunction,传递1个参数(回调函数),期望0个返回值
if (lua_pcall(L, 1, 0, 0) != 0)
{
fprintf(
stderr, "Error calling mainFunction: %s\n", lua_tostring(L, -1));
lua_pop(L, 1); // 弹出错误信息
return 1;
}
lua_close(L);
return 0;
}
编译命令:gcc lua_c_callfunction.c -o lua_c_callfunction -llua5.3
。
在上述C代码中分别将两个函数使用lua_getglobal
压入堆栈,那么怎么知道调用的是mainFunction
而不是callbackFunction
函数呢,问了几遍Copilot也没有答案。
直到修改了一次lua_pcall
函数的参数个数,发现将其由1
修改为0
时,调用的是callbackFunction
,才确定lua_pcall
确定真正要调用函数的位置是从栈顶开始,经过指定的参数(第2个参数指定参数个数),然后会找到调用函数位置。
在上述例子中,lua_pcall(L, 1, 0, 0)
时调用的是mainFunction
,lua_pcall(L, 0, 0, 0)
时调用的是callbackFunction
。