【问题标题】:lua_gettop returns 0 but the stack does not behave like it is emptylua_gettop 返回 0 但堆栈的行为不像是空的
【发布时间】:2019-01-30 08:26:35
【问题描述】:

当我运行以下代码时:

pState = luaL_newstate();
if( !pState )
    return false;

luaL_requiref( pState, "_G", luaopen_base, 1 );
luaL_requiref( pState, "table", luaopen_table, 1 );
luaL_requiref( pState, "string", luaopen_string, 1 );
luaL_requiref( pState, "math", luaopen_math, 1 );
luaL_requiref( pState, "debug", luaopen_debug, 1 );
luaL_requiref( pState, "package", luaopen_package, 1 );
lua_pop( pState, 6 );
// Clear stack 
lua_settop( pState, 0 );

//...

lua_newtable( pState );
lib_indx = lua_gettop( pState );
CLuaManager::PrintStack( pState );

lib_indx 的值为 0,而我的 PrintStack 函数(与 documentation 中的函数相同)显示堆栈为空。但是,如果我尝试执行任何会使用堆栈顶部的值的操作,它们的工作方式就好像表格位于堆栈顶部一样。例如以下代码:

lua_newtable( pState );
lib_indx = lua_gettop( pState );
lua_setglobal( pState, "TestTable" );

不会报错,通过脚本可以访问“TestTable”表:

function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end

print("TestTable:", dump(TestTable))

注释掉lua_setglobal( pState, "TestTable" ); 行会得到TestTable: nil 的输出,而取消注释则会得到TestTable: { }。这表明该表被设置为全局值TestTable。但是,lib_indx 仍然为零!那么 Lua 在哪里找到表呢?

【问题讨论】:

  • 你确定pState是一个创建的Lua状态对象吗?你能提供一个minimal reproducible example 来展示这种行为吗?我问这个是因为 0 never 是堆栈中的有效索引;如果luaL_checktype( pState, 0, LUA_TTABLE ) 有效,那只是偶然。
  • @NicolBolas 哎呀!那是我的错误,你说得对,这确实解释了为什么会这样。有趣的是它只适用于LUA_TTABLE 类型。但无论如何,尽管文档声称 lua_newtable 将其推送到堆栈上,但我的堆栈不包含任何内容。而且我的 Lua 状态对象实际上是有效的,到目前为止,一切都按预期工作。我会把我的例子改成正确的。

标签: c++ lua


【解决方案1】:

我发现了行为的根源。放错位置的lua_pop 显然导致堆栈的大小为负数,因此新表被添加到堆栈中,但位于意外索引处。

【讨论】:

    猜你喜欢
    • 2016-07-07
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多