[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Callbacks, upvalues and memory management
- From: Alex Ames <alexander.ames+lua@...>
- Date: Fri, 29 Jul 2011 22:54:37 -0700
> The problem is that an anonymous function passed to on_click() has an
> upvalue which refers to the button, which implies that the button's __gc
> method will not be called while the function exists. But the function is
> referenced in the "refs" table and will not vanish until the destruction
> of C++ object. Hence we get a circular reference which causes a memory
> leak.
I had a similar problem when I was writing my own lua wrapper code.
The solution I ended up going with was to not have Lua hold the full
object as userdata, but rather to have it hold a pointer to the object
as userdata. That means you may have many userdata that actually point
at the same object. You then keep a reference count of how many
userdatas represent your object. You can do the reference counting by
using the object itself as a lightuserdata as the key into a table
containing the reference counts. When the __gc metamethod is called
and frees the last reference to an object, you can delete it and
free/delete/nil any data it was using.
So this code:
> Button* self = (Button*)lua_touserdata(L, 1);
becomes this:
> Button* self = *(Button**)lua_touserdata(L, 1);
And for extra clarity, you can wrap that in a template so you have a
nice function like this:
<template T>
lua_to(lua_State* L, int i) {
return *(T**)lua_touserdata(L, i);
}
For a more robust example, have a look at this library I posted
ealier, which sounds like it does roughly what you're trying to do:
https://bitbucket.org/alexames/luawrapper