lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Tue, Nov 20, 2007 at 07:41:31PM -0600, Matt Campbell wrote:
> Memory for userdata is allocated and freed by Lua.  There's nothing 
> special about userdata in tables, at least from the perspective of the 
> Lua C API.  Lua has no knowledge of C++ constructors and destructors, 
> but it does support __gc metamethods in the metatables of userdata.  So 
> to wrap an instance of a class called Foo in Lua userdata, you'd write 
> code like this:
> 
> Foo **pp = (Foo *) lua_newuserdata(L, sizeof(Foo *));
> *pp = new Foo;
> 
> Then you'd set the new userdata's metatable to a table with a __gc 
> metamethod like this:
> 
> static int foo_gc(lua_State *L) {
>   Foo **pp = (Foo **) lua_touserdata(L, 1);
>   if (*pp) {
>     delete *pp;
>     *pp = NULL;
>   }
>   return 0;
> }

This is a good starting point; in order to reduce the memory allocations
you can also put the object directly into the userdata with placement new:

template< typename T >
void my_newuserdata( lua_State * L ) {
   new ( reinterpret_cast< T * >( lua_newuserdata( L, sizeof( T ) ) ) ) T();
}

template< typename T >
int my_gc( lua_State * l ) {
   reinterpret_cast< T * >( lua_touserdata( L, 1 ) )->~T();
   return 0;
}

(Untested; my actual code is more complicated, but this should show the
general idea...)

Regards, Colin