【问题标题】:Dynamically find out the number of return values of Lua function()?动态找出Lua function()的返回值个数?
【发布时间】:2018-11-27 23:01:12
【问题描述】:

我想知道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++ 中动态处理返回值?

【问题讨论】:

标签: c++ function lua return-value


【解决方案1】:

这是对现有答案的扩展,概述了可能的实现。一旦将实现示例添加到现有示例中,我将立即删除此答案。

#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

【讨论】:

【解决方案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

【讨论】:

  • 非常感谢。你介意发布这个的实际例子吗? (就像我发布的一样)我会很感激的!
  • 那我得下载Lua并写一个测试程序。
  • 谢谢,我等着。 :)
猜你喜欢
  • 2016-09-27
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 2012-03-29
  • 2017-10-09
  • 2022-01-09
相关资源
最近更新 更多