c++ - Lua、C++ 和消失的元表

标签 c++ lua metatable

背景

我在游戏中与 Watusimoto 合作 Bitfighter .我们使用 LuaWrapper 的变体将我们的 c++ 对象与游戏中的 Lua 对象连接起来。我们还使用了一个名为 lua-vec 的 Lua 变体。加速 vector 运算。

一段时间以来,我们一直致力于解决一个未能解决的错误。将发生随机崩溃,表明元表已损坏。参见 here对于 Watusimoto 关于此问题的帖子。我不确定这是因为损坏的元表,并且看到了一些我想在这里询问的非常奇怪的行为。

问题表现

例如,我们创建一个对象并将其添加到如下级别:

t = TextItem.new()
t:setText("hello")
levelgen:addItem(t)

但是,游戏有时(并非总是)会崩溃。出现错误:

attempt to call missing or unknown method 'addItem' (a nil value)

根据对上述 Watusimoto 帖子的回答给出的建议,我将最后一行更改为以下内容:

local ok, res = pcall(function() levelgen:addItem(t) end)

if not ok then
    local s = "Invalid levelgen value: "..tostring(levelgen).." "..type(levelgen).."\n"

    for k, v in pairs(getmetatable(levelgen)) do 
        s = s.."meta "..tostring(k).." "..tostring(v).."\n"
    end

    error(res..s)
end

如果从中调用方法时出错,这会打印出 levelgen 的元表。

然而,这太疯狂了,当它失败并打印出元表时,元表完全它应该如何(正确的 addItem 调用和一切) .如果我在脚本加载时打印 levelgen 的元表,并且当它使用上面的 pcall 失败时,它们是相同的,每个调用和指向 userdata 的指针都是相同的,并且应该如此是。

就好像 levelgen 的元表随机自发地消失了。

谁知道发生了什么事?

谢谢

注意:只有 levelgen 对象不会发生这种情况。例如,它也发生在上面提到的 TestItem 对象上。事实上,同样的代码在我的计算机上的 levelgen:addItem(t) 行崩溃了,但在另一位开发人员的计算机上的 t:setText("hello") 行崩溃了具有相同的错误消息 missing or unknown method 'setText' (a nil value)

最佳答案

与任何谜团一样,您需要一层一层地揭开它。我建议执行 Lua 正在执行的相同步骤,并尝试检测所采用的路径与您的预期有何不同:

getmetatable(levelgen).__index 返回什么?如果是表格,则检查其内容是否有 addItem。如果它是一个函数,则尝试使用 (table, "addItem") 调用它并查看它返回什么。

检查 getmetatable 在调用前后(或失败时)是否返回对同一对象的引用。

调用是否经过多个级别的元表间接寻址?如果是这样,请尝试通过显式调用遵循相同的路径并查看差异在哪里。

如果没有其他引用,您是否使用了可能导致值消失的键?

能否在检测失败时提供一个“默认”值,以后继续看是否再次“找到”这个方法?或者当它坏了,之后的每个电话都坏了?

如果您为 addItem 保存一个正确的值并在检测到它损坏时“修复”它会怎么样?

如果您只是简单地处理错误(如您所做的那样)并调用它 10 次会怎么样?它会至少显示一次有效结果吗(在失败之后)? 100次?如果你一直调用同一个方法,当它起作用时,它会失败吗?这可能会帮助您找出更可重现的错误。

我不熟悉 LuaWrapper,无法提供更具体的问题,但如果我是你,我会采取这些步骤。

关于c++ - Lua、C++ 和消失的元表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14916985/

相关文章:

C++在另一个内部创建窗口

command-line - 交互式 lua : command line arguments

PHP 严格标准 : Only variables should be passed by reference in . lib

c - Lua C API - 将属性映射到函数

lua - Lua中元表访问时的时间复杂度

c++ - Lua 5.2 - 对象中的 C++ 对象(使用 lua_lightuserdata)

c++ - static const 成员是否有内部链接?

c++ - 将 3d 模型导入 Direct3D 11 示例

c++ - 我正在尝试对运算符 '+'进行二进制重载,但输出错误,我不明白为什么?

python - 为什么即使我获得了所需的输出,我仍会收到此错误 "Wrong number of args calling Redis command From Lua script"