2010-08-26 11 views
5

Supposant la situation suivante:Lua: collecte des ordures + userdata

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; 
} 

Lorsque la fonction est appelée à partir L_rgb Lua deux allocations se produisent. Lua alloue de nouvelles données utilisateur et la fonction constructeur rgb alloue pour la structure. Qu'advient-il de la variable userdata lorsque la variable sort du champ d'application de Lua? Si ce sont les ordures collectées, qu'arrive-t-il à l'allocation de la structure?

Répondre

12

Vous avez deux approches à cette situation, et les deux pourraient s'appliquer à votre cas spécifique. D'autres cas vous poussent à choisir l'un plutôt que l'autre.

  1. Vous pouvez faire comme vous le faites dans votre échantillon, et utiliser malloc() pour obtenir votre bloc de données privées, et stocker un pointeur dans un userdata complet. Si vous faites cela, alors vous devez définir une metable sur les données d'utilisateur, et utiliser son métaméthode __gc pour libérer le bloc alloué lorsque les données d'utilisateur sont récupérées.

  2. Vous pouvez utiliser les données d'utilisateur en tant qu'allocation pour votre bloc de données privé, en appelant lua_newuserdata() à la place de malloc(). Dans ce cas, vous n'avez pas besoin d'avoir une métaméthode __gc parce que Lua gérera directement la durée de vie de l'allocation. Vous pouvez toujours avoir une méta-donnée pour que vous puissiez utiliser son entrée __index pour créer l'apparence des membres nommés r, g et b qui récupèrent leurs valeurs à partir de votre structure.

De toute façon, vous devez penser à la gestion des erreurs.

+2

La méthode n ° 2 vous soulagera des allocations de suivi - sur les erreurs Lua et les retours de pile, le GC de Lua suivra et relâchera les blocs de code selon les besoins. – u0b34a0f6ae

+0

Y at-il un changement, vous pouvez aider ici: http://stackoverflow.com/questions/41080633/can-i-load-additional-functions-in-base-open-without-breaking-lua-state? – displayname

2

Ajoutez une méta-donnée à vos données utilisateur et définissez la clé __gc à votre fonction de désallocation. Voir the docs

+0

Une idée de ce que le problème est ici: http://stackoverflow.com/questions/41080633/can-i-load-additional-functions-in-base-open-without-breaking-lua-state? – displayname