2017-08-07 100 views
3

以下示例僅用於演示問題/問題;在現實中,我有創建 並返回許多不同的userdata對象的功能,以及其中一些我可能想要調用Lua垃圾回收器的功能。何時允許在使用lua_newuserdata的情況下調用lua_gc時使用lua_newuserdata

此外,我使用Lua版本5.3.3,同時在Windows和Linux上運行。爲簡單起見,未顯示錯誤處理。

我有一個C++類通過標準的userdata暴露給Lua,例如, Roberto Ierusalimschy撰寫的「Lua編程」。 我的問題是,我不知道何時Lua確實有對我的對象的引用,所以當我允許通過C++ lua_gc函數調用 垃圾回收器時?

我有例如具有構造函數和析構函數的標準Foo C++類。並且使用名爲ReleaseFoo的__gc入口函數定義了一個metatable「FOO」 ,同樣如圖所示。

我通過下面的C創建在Lua一個實例++代碼:

static int NewFoo(lua_State* L) 
{ 
    Foo** foo; 
    foo = (Foo**) lua_newuserdata(L, sizeof(Foo**)); 
    *foo = new Foo(); 
    luaL_getmetatable(L, "FOO"); 
    lua_setmetatable(L, -2); 

    // QUESTION: Can I call lua_gc(L, LUA_GCCOLLECT, 0) here without 
    //   risking my user data object being garbage collected. 
    //   As I see it, Lua does not yet have a reference 
    //   to my user data object. 

    return 1; 
} 

static int ReleaseFoo(lua_State* L) 
{ 
    Foo* foo = *(Foo**)lua_touserdata(L,1); 
    if (foo) 
    { 
    delete foo; 
    foo = NULL; 
    } 
    return 0; 
} 

在Lua中,使用它看起來像(所以只有C++函數NewFoo的返回(L)的基準建立後,但我可以調用如圖所示的垃圾收集器):

LUA> foo = NewFoo() 

回答

3

lua_setmetatable所以存在引用您的用戶數據對象不從堆棧中刪除對象。所以Lua不會收集它。

+0

謝謝,你一定是對的。引用必須在堆棧上,直到它被轉移到Lua變量「foo」。 –

相關問題