假设以下情况:
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;
}
当从Lua调用L_rgb函数时,会发生两次分配。 Lua分配新的userdata并为结构分配rgb构造函数。当变量超出Lua的范围时,userdata变量会发生什么?如果是垃圾收集结构的分配会发生什么?
答案 0 :(得分:12)
您有两种解决此问题的方法,两种方法都适用于您的具体情况。其他情况会让你更强烈地选择一个而不是另一个。
您可以像在示例中那样进行操作,并使用malloc()
获取私有数据块,并在完整的用户数据中存储指向它的指针。如果执行此操作,则必须在userdata上设置metatable,并在userdata收集垃圾时使用其__gc
元方法释放已分配的块。
您可以使用userdata本身作为私人数据块的分配,方法是调用lua_newuserdata()
代替malloc()
。在这种情况下,您不需要__gc
元方法,因为Lua将直接管理分配的生命周期。您可能仍希望拥有一个元表,以便您可以使用其__index
条目来创建名为r
,g
和b
的成员的外观,以从中检索其值你的结构。
无论哪种方式,您都需要考虑错误处理。
答案 1 :(得分:2)
向您的userdata添加metatable,并将__gc
键设置为释放函数。见the docs