LUA_MULTRET未按预期工作

LUA_MULTRET未按预期工作,lua,Lua,这几乎是一个复制品;但是,答案表明没有解决我的问题,而且我没有直接使用luaL\u dostring()宏(尽管我使用的是它扩展到的同一对调用)。鉴于该计划: #include <string> #include <stdio.h> #include <stdlib.h> #include <lua.hpp> static int _foo(lua_State* L) { lua_pushinteger(L, 1); lua_pu

这几乎是一个复制品;但是,答案表明没有解决我的问题,而且我没有直接使用
luaL\u 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;
}

我正在使用Lua5.1.5…

在第一次调用中,您将C函数foo推到堆栈上,然后调用它。但是luaL_loadstring创建了一个块,所以在第二次和第三次调用中,您推送一个块,然后调用它,但该块不返回任何内容,该块只调用foo()。因此

在Lua堆栈上创建3个nil,因为Lua确保您请求的3个值都在那里,即使chunk没有返回任何值。也

lua_pcall(L, 0, LUA_MULTRET, 0);
不返回任何内容,因为区块未返回任何内容

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

lua_getglobal(L, "foo");
lua_pcall(L, 0, LUA_MULTRET, 0);
或者,使区块返回foo()返回的内容:

luaL_loadstring(L, "return foo()");
lua_pcall(L, 0, LUA_MULTRET, 0);

谢谢@Scholli,这帮我找到了解决我特定问题的方法,所以我认为这个答案是正确的。我正在尝试制作一个调试控制台(实际上,我只是使用socat写入主机应用程序正在侦听的Unix域套接字)。我在主机应用程序中接收到的字符串看起来有点像
foo.bar.get_属性(“baz”,false)
,因此按名称在堆栈上推送函数有点不方便。但是在
luaL\u loadstring()
调用中将“return”前置到字符串非常有效。(我在队列中进行了编辑,将此添加到您的答案中…)谢谢,根据SO政策,接受它是正确的做法()。关于你对我的答案所做的编辑,最好是发表评论,让答案的作者决定怎么做。这就是为什么SO版主拒绝了您的编辑。编辑别人的帖子是为了在一个很小的改变,你自己去做比解释什么需要修改要快的时候使用。你在评论中提供的信息足够清楚,我应该编辑我的答案(所以我就这么做了)。
lua_getglobal(L, "foo");
lua_pcall(L, 0, LUA_MULTRET, 0);
luaL_loadstring(L, "return foo()");
lua_pcall(L, 0, LUA_MULTRET, 0);