2

我在使用 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 尝试调用一个 nil 值

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

行为与 5.1 版本相同。

4

2 回答 2

1

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

编辑: OP 说“我怎样才能从空堆栈中获取字符串?”。我的回答是:为什么你想从一个空堆栈中获取一些东西,当你知道它是空的,因为lua_gettop返回了 0?

底线:

  • 调用前堆栈为空lua_pcall。这是一个错误。Lua 恢复了,但你不能指望它。
  • 之后堆栈为空lua_pcall。Lua 这么认为,并通过lua_gettop.
  • 您不应该尝试从空堆栈中获取值。打印的字符串只是 留下的垃圾lua_pcall,但你不能指望它。
于 2012-05-15T18:36:36.857 回答
0

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

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

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

于 2012-05-26T18:11:59.797 回答