简体   繁体   English

动态找出Lua function()返回值的数量?

[英]Dynamically find out the number of return values of Lua function()?

I wonder if it is possible to dynamically find out the number of return values of Lua function in C++. 我想知道是否有可能动态地找出C ++中Lua函数的返回值数量。

For example, I can pass and return values to/from Lua function in C++ like this. 例如,我可以像这样在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 */

As you can see, it expects 1 returned value from Lua function. 如您所见,它期望Lua函数返回1个值。 So if user returns more(or less) than 1 value in Lua function, it will not work properly. 因此,如果用户在Lua函数中返回的值大于(或小于)1,它将无法正常工作。

Is there any possible solution to detect the number of returned values from Lua function in advance so I can dynamically process the returned values in C++? 是否有任何可能的解决方案可以预先检测Lua函数返回的值的数量,以便我可以在C ++中动态处理返回的值?

This is an extension to the existing answer, outlining a possible implementation. 这是对现有答案的扩展,概述了可能的实现。 I will remove this answer as soon as an implementation example is added to the existing one. 一旦将实施示例添加到现有示例中,我将删除此答案。

#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

https://www.lua.org/manual/5.3/manual.html#lua_call (also applies to lua_pcall): https://www.lua.org/manual/5.3/manual.html#lua_call (也适用于lua_pcall):

The number of results is adjusted to nresults, unless nresults is LUA_MULTRET. 除非nresults为LUA_MULTRET,否则将结果数调整为nresults。 In this case, all results from the function are pushed; 在这种情况下,该函数的所有结果都会被推送; Lua takes care that the returned values fit into the stack space, but it does not ensure any extra space in the stack. Lua会确保返回的值适合堆栈空间,但不能确保堆栈中有任何额外的空间。 The function results are pushed onto the stack in direct order (the first result is pushed first), so that after the call the last result is on the top of the stack. 函数结果按直接顺序被推入堆栈(第一个结果首先被推入),因此调用后最后一个结果位于堆栈顶部。

So it looks like you can save the previous stack top (use lua_gettop ), subtract the number of arguments and 1 for function itself, do the call, then get the stack top again and the difference is the number of return values. 因此,看起来您可以保存以前的堆栈顶部(使用lua_gettop ),减去参数个数,并为函数本身减去1,进行调用,然后再次获取堆栈顶部,不同之处在于返回值的数量。 Remember to pass LUA_MULTRET for nresults . 请记住将LUA_MULTRET传递给nresults

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM