2010-08-26 83 views
5

假設以下情況:的Lua:垃圾收集用戶數據+

typedef struct rgb_t {float r,g,b} rbg_t; 

// a function for allocating the rgb struct 
rgb_t* rgb(r,g,b) { 
rgb_t* c = malloc(sizeof(rgb_t)); 
c->r=r; 
c->g=g; 
c->b=b; 
return c; 
} 

// expose rgb creation to lua 
int L_rgb (lua_State* L) { 
rgb_t** ud = (rgb_t **) lua_newuserdata(L, sizeof(rgb_t *)); 
*ud = rgb(lua_tonumber(L,1),lua_tonumber(L,2),lua_tonumber(L,3)); 
return 1; 
} 

當L_rgb功能從Lua稱爲兩個撥款發生。 Lua分配新的userdata併爲結構分配rgb構造函數。當變量超出Lua中的作用域時,userdata變量會發生什麼變化?如果它是垃圾收集結構的分配會發生什麼?

回答

12

對於這種情況,您有兩種方法,並且兩種方法都適用於您的特定情況。其他案例會讓你更強烈地選擇一個。

  1. 爲您的樣品做你能做的,並使用malloc(),讓您的私人數據塊,並存儲指向它在一個完整的用戶數據。如果您這樣做,那麼您必須在用戶數據上設置metatable,並在用戶數據被垃圾收集時使用其元數據方法釋放分配的塊。

  2. 通過調用lua_newuserdata()代替malloc(),可以將userdata本身用作私人數據塊的分配。在這種情況下,您不需要有一個__gc元方法,因爲Lua將直接管理分配的生命週期。您可能仍希望具有metatable,以便您可以使用其__index條目來創建名爲rgb的成員的外觀,以從您的結構中檢索它們的值。

無論哪種方式,您都需要考慮錯誤處理。

+2

方法2將減輕你跟蹤分配 - 在Lua錯誤和堆棧倒回上,Lua的GC仍然會根據需要跟蹤和釋放代碼塊。 – u0b34a0f6ae 2010-08-27 14:54:36

+0

有沒有可以幫助你的變化:http://stackoverflow.com/questions/41080633/can-i-load-additional-functions-in-base-open-without-breaking-lua-state? – displayname 2016-12-12 00:31:29

2

將metatable添加到您的userdata中,並將__gc鍵設置爲您的釋放函數。請參閱the docs

+0

任何想法是什麼問題在這裏:http://stackoverflow.com/questions/41080633/can-i-load-additional-functions-in-base-open-without-breaking-lua-state? – displayname 2016-12-12 00:31:45