LUA_MULTRET没有按预期工作

eva*_*low 5 lua

几乎这个问题的重复; 然而,答案建议有没有解决我的问题,我不使用luaL_dostring()直接宏(虽然我正在使用相同的一对调用它扩展到).鉴于此计划:

#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <lua.hpp>

static int _foo(lua_State* L)
{
    lua_pushinteger(L, 1);
    lua_pushinteger(L, 2);
    lua_pushinteger(L, 3);
    printf("In foo(): pushed %d elements...\n", lua_gettop(L));
    return 3;
}

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    lua_pushcfunction(L, _foo);
    lua_setglobal(L, "foo");

    // This leaves three results on the stack...
    lua_pushcfunction(L, _foo);
    lua_pcall(L, 0, LUA_MULTRET, 0);
    int nresults = lua_gettop(L);
    printf("After foo(): %d results left on the stack...\n", nresults);
    lua_settop(L, 0);

    // ... and so does this.
    luaL_loadstring(L, "foo()");
    lua_pcall(L, 0, 3, 0);
    nresults = lua_gettop(L);
    printf("After foo(): %d results left on the stack...\n", nresults);
    lua_settop(L, 0);

    // But this does NOT. Why?
    luaL_loadstring(L, "foo()");
    lua_pcall(L, 0, LUA_MULTRET, 0);
    nresults = lua_gettop(L);
    printf("After foo(): %d results left on the stack...\n", nresults);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么最后一次调用lua_pcall(L, 0, LUA_MULTRET, 0) 不会在堆栈上留下任何结果?运行上述程序的输出是:

In foo(): pushed 3 elements...
After foo(): 3 results left on the stack...
In foo(): pushed 3 elements...
After foo(): 3 results left on the stack...
In foo(): pushed 3 elements...
After foo(): 0 results left on the stack...
Run Code Online (Sandbox Code Playgroud)

我正在使用Lua 5.1.5 ......

Oli*_*ver 6

在第一次调用中,您将C函数foo推入堆栈然后调用它.但是luaL_loadstring创建了一个块,所以在第二次和第三次调用中你推送一个块然后调用它,但是块没有返回任何东西,块只调用foo().于是

lua_pcall(L, 0, 3, 0);
Run Code Online (Sandbox Code Playgroud)

在Lua堆栈上创建3个nil,因为Lua确保你提出的3个值都在那里,即使chunk没有返回.也

lua_pcall(L, 0, LUA_MULTRET, 0);
Run Code Online (Sandbox Code Playgroud)

什么都不返回,因为块没有返回任何内容

如果你想从Lua执行foo,请将foo全局变量放在堆栈上:

lua_getglobal(L, "foo");
lua_pcall(L, 0, LUA_MULTRET, 0);
Run Code Online (Sandbox Code Playgroud)

或者,使块返回foo()返回的内容:

luaL_loadstring(L, "return foo()");
lua_pcall(L, 0, LUA_MULTRET, 0);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@Scholli,这帮助我找到了解决我特定问题的方法,所以我将这个答案标记为正确.我正在尝试创建一个调试控制台(实际上,我只是使用socat写入主机应用程序正在侦听的Unix域套接字).我在主机应用程序中收到的字符串看起来有点像``foo.bar.get_property("baz",false)``,因此在名称_上推送堆栈上的函数有点不方便.但是在"luaL_loadstring()``调用中将"return"前置到字符串中效果很好.(我在队列中有一个编辑,将其添加到你的答案......) (2认同)