5

バックグラウンド

Bitfighter というゲームで Watusimoto と仕事をしています。LuaWrapper のバリエーションを使用して、c++ オブジェクトをゲーム内の Lua オブジェクトに接続します。また、 lua-vecと呼ばれる Lua のバリエーションを使用して、ベクトル操作を高速化します。

私たちはしばらくの間、解決できなかったバグを解決するために取り組んできました。メタテーブルの破損を示唆するランダムなクラッシュが発生します。この問題に関する 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からメソッドを間違って呼び出した場合に、if 何かのメタテーブルを出力します。

ただし、これはクレイジーです。失敗してメタテーブルを出力すると、メタテーブルはまさにaddItem(正しい呼び出しとすべてで)あるべき姿になります。levelgenスクリプトの読み込み時にメタテーブルを出力し、pcall上記の使用に失敗した場合、それらは同一であり、ユーザーデータへのすべての呼び出しとポインターは同じである必要があります。

メタテーブル forlevelgenがランダムに自然に消えていくようなものです。

何が起こっているのか誰にも分かりますか?

ありがとうございました

注:levelgenこれは、オブジェクトだけでは発生しません。たとえば、TestItem上記のオブジェクトでも発生しています。実際、同じコードが自分のコンピューターの行levelgen:addItem(t)でクラッシュしますが、別の開発者のコ​​ンピューターでt:setText("hello")は同じエラー メッセージの行でクラッシュします。missing or unknown method 'setText' (a nil value)

4

3 に答える 3

2

問題は、次のようなクラスまたは構造体があることだと強く思います。

struct Foo
{
    Bar bar;
    // Other fields follow
}

そして、LuaWrapper を介して Foo と Bar の両方を Lua に公開しました。ここで重要なのは、それbarが構造体の最初のフィールドであることですFoo。または、他の基本クラスから継承するクラスがあり、派生クラスと基本クラスの両方が LuaWrapper に公開されている場合があります。

LuaWrapper は Identifier と呼ばれる関数を使用して、各オブジェクトを一意に追跡します (特定のオブジェクトがすでに Lua 状態に追加されているかどうかなど)。デフォルトでは、オブジェクト アドレスをキーとして使用します。上記のような場合、Foo と Bar の両方がメモリ内で同じアドレスを持つ可能性があるため、LuaWrapper が混乱する可能性があります。

これにより、メソッドを検索しようとすると、間違ったオブジェクトのメタテーブルが取得される可能性があります。明らかに、間違ったメタテーブルを見ているため、必要なメソッドが見つからないため、メタテーブルのエントリが不思議なことに失われたように見えます。

1 つの巨大な山ではなく、タイプごとに各オブジェクトのデータを追跡する変更をチェックインしました。コピーの LuaWrapper をリポジトリから最新のものに更新すると、問題が修正されると確信しています。

于 2013-02-23T03:49:10.803 に答える