0

CでSimple Luaクラスを実装しました。クラスの使用法:

require("test")
function foo()
    local t1 = test()
    local t2 = test()
    t1:attach(t2)
    return t1
end
o = foo()
-- some code
o = nil

アタッチ機能:

int class_attach(lua_State *L)
{
    module_data_t *mod = luaL_checkudata(L, 1, "test");
    luaL_checktype(L, 2, LUA_TUSERDATA);
    module_data_t *child = lua_touserdata(L, 2);
    printf("%p->%p\n", (void *)mod, (void *)child);
    return 0;
}

関数 t2 から戻った後、オブジェクトは gc によって消去されます。それを防ぐことは可能ですか?t1 オブジェクトと t2 オブジェクト間の参照を設定しますか? (親モジュール (t1) が消去された後にのみ、(t2 オブジェクトの) __gc メタメソッドを呼び出します)。

簡単な方法はテーブルを使用することです:

function foo()
    ret = {}
    ret[1] = test()
    ret[2] = test()
    ret[1]:attach(ret[2])
    return ret
end

しかし、それは楽しい方法ではありません。ありがとう!

4

2 に答える 2

0

Lua レジストリで設定できます。これは事実上、C コードでのみアクセスできるグローバル テーブルです。設定できますregistry[t1] = t2;t1でこれを適切に設定解除する限り__gc1:nこれは、たとえばregistry[t1].insert(t2)複数の「子」に対して行うことができるように、マッピングに合わせてスケーリングすることもできます。

于 2012-06-30T08:12:33.890 に答える
0

私は過去に同じ問題を抱えていました。これの単純な理由は、Lua が C コードで確立された接続を認識していないためです (現在は何もありませんが、どこかで行われると思います)。

テーブル アプローチを行う必要はありません。Lua 側でも 2 つのオブジェクト/テーブル/その他のものをリンクするだけです。

function foo() 
    local t1 = test() 
    local t2 = test() 
    t1:attach(t2)
    t1._dummy_link = t2
    return t1 
end 

これは 1 対 1 の関係にのみ有効であることを覚えておいてください。より複雑なものについては、ある種のテーブルまたは同様のアプローチを使用する必要があります。これを行うためのおそらく最もクリーンな方法は、Lua 側でリンクを行い、実行する C コードがある場合に備えて C にコールバックを追加することです。

于 2012-06-30T08:08:28.347 に答える