Lua C API:pcall错误后堆栈为空

时间:2012-05-15 16:16:58

标签: c lua

使用Lua C API时遇到问题。当pcall(C API函数)失败时,错误将被推送到堆栈上。 lua_tostring在堆栈上显示错误,但lua_gettop显示堆栈为空。

#include <lua5.2/lauxlib.h>
#include <lua5.2/lua.h>
#include <lua5.2/lualib.h>

int main()
{
    lua_State *L = luaL_newstate();
    lua_pcall(L, 0, 0, 0);
    printf("%d\n", lua_gettop(L)); // outputs 0, indicating empty stack
    printf("%s\n", lua_tostring(L, -1)); // outputs "attempt to call a nil value", indicating non-empty stack
}

编译:gcc main.c`pkg-config --cflags lua5.2``pkg-config --libs lua5.2`

此程序显示:     0     试图调用零值

lua_gettop(L)返回堆栈大小。在这里,我得到0.如何从空堆栈中获取字符串?

行为与5.1版本相同。

2 个答案:

答案 0 :(得分:1)

这已在Lua邮件列表中得到解答。行为是正确的:您需要将一个函数推入堆栈以调用它。 luaL_newstate之后的堆栈为空。

编辑: OP说“如何从空堆栈中获取字符串?”。我的回答是:当你知道它是空的,因为lua_gettop返回0时,你为什么要从空堆栈中获取某些内容?

底线:

  • 在调用lua_pcall之前,堆栈为空。这是一个错误。 Lua恢复了,但你不能指望它。
  • lua_pcall后堆栈为空。 Lua这么认为并通过lua_gettop告诉你。
  • 您不应该尝试从空堆栈中获取值。打印的字符串只是lua_pcall留下的垃圾,但你不能指望它。

答案 1 :(得分:0)

据我所知,lua_pcall不会推送错误字符串。相反,它会覆盖堆栈顶部的值(因为应该始终至少是一个函数; p)。因此,lua_pcall(或者,更确切地说,我认为是debug.traceback)盲目地覆盖堆栈的顶部,而不是修改堆栈指针。

因此,当lua_pcall返回时,该值位于堆栈顶部,但堆栈指针表示堆栈为空(就像您调用lua_pcall时那样)。

我认为这是一种避免更严重错误的措施(例如,如果存在内存损坏或内存不足错误,我们不希望为错误消息分配更多的堆栈空间吗?)。< / p>