我想知道是否有可能动态地找出C ++中Lua函数的返回值的数量。
例如,我可以像这样在C ++中传递和返回Lua函数的值。
/* push functions and arguments */
lua_getglobal(L, "f"); /* function to be called */
lua_pushnumber(L, x); /* push 1st argument */
lua_pushnumber(L, y); /* push 2nd argument */
/* do the call (2 arguments, 1 result) */
if (lua_pcall(L, 2, 1, 0) != 0)
error(L, "error running function `f': %s", lua_tostring(L, -1));
/* do something with the result */
如您所见,它期望从Lua函数返回1个值。因此,如果用户在Lua函数中返回的值多于(或小于)1,则无法正常工作。
是否有任何可能的解决方案提前检测Lua函数返回值的数量,以便我可以在C ++中动态处理返回的值?
答案 0 :(得分:3)
这是对现有答案的扩展,概述了可能的实施方式。一旦将实现示例添加到现有示例中,我将删除此答案。
#include <iostream>
#include <lua.hpp>
int main(int argc, char *argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <script.lua>\n";
return 1;
}
lua_State * L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, argv[1]) != 0) {
std::cerr << "lua: " << lua_tostring(L, -1) << '\n';
lua_close(L);
return 1;
}
int stack_size = lua_gettop(L);
lua_getglobal(L, "f");
lua_pushnumber(L, 1);
lua_pushnumber(L, 2);
if (lua_pcall(L, 2, LUA_MULTRET, 0) != 0) {
std::cerr << "lua: " << lua_tostring(L, -1) << '\n';
lua_close(L);
return 1;
}
int num_returns = lua_gettop(L) - stack_size;
std::cout << num_returns << " values returned\n";
lua_close(L);
}
function f(x,y)
return 1,2,3,"Hello World",{},function() end
end
6 values returned
答案 1 :(得分:2)
https://www.lua.org/manual/5.3/manual.html#lua_call(也适用于lua_pcall):
结果数量调整为nresults,除非nresults是LUA_MULTRET。在这种情况下,推送该函数的所有结果; Lua注意返回的值适合堆栈空间,但它不能确保堆栈中有任何额外的空间。函数结果按直接顺序压入堆栈(第一个结果先被推送),因此在调用之后,最后一个结果位于堆栈顶部。
所以看起来你可以保存前面的堆栈顶部(使用lua_gettop
),减去参数的数量,减去函数本身的1,执行调用,然后再次获得堆栈顶部,差异就是数字返回值。请务必将LUA_MULTRET
传递给nresults
。