lua-users home
lua-l archive

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


On Sat, Aug 15, 2009 at 12:51 PM, Michael
Newberry<mnewberry@mirametrics.com> wrote:
> OK, Here's what I have come up with (but it doesn't work):
>
> When the script starts, the app executes this new function:
>
> void SetupCDataGC( struct lua_State* L )    // setup garbage collection
> {
>   luaL_newmetatable( L, "CData_type" ); // create metatable for CData
>   lua_pushstring( L, "__gc" );
>   lua_pushcfunction( L, CDataDelete );
>   lua_settable( L, -3 );
> }
>
> The new userdata delete function is declared like this:
>
> int CDataDelete( struct lua_State* L )
> {
>   // deletion stuff
>   return 0;
> }
>
> When the lua script creates the CData table (a lua "class"), it calls a
> CFunction to create the C++ object (existing code).  Inside that function, I
> added the following code:
>
>   CData** ptr = (CData**)lua_newuserdata( L, sizeof(CData*) );
>   *ptr = pData;
>   luaL_getmetatable( L, "CData_type" );
>   lua_setmetatable( L, -2 );
>
>   lua_pushlightuserdata( L, pData );    // return the C++ object's pointer
> to the script
>   return 1;

You are creating userdata, but not returning it, instead just
returning lightuserdata. This can't work.

Not seeing all your code, but since you aren't returning the userdata,
it will become unreferenced immediately after you create it, and
garbage collected sometime later, causing your lightuserdata to point
to a deleted object at some random future time.

I think what you have done in the past is just bind a bunch of c fns
into lua, wrap them in a lua object/table, make a table key that is
light userdata, and write "methods" in lua that pass in that light
userdata. Once you get userdata working, you'll find that it offers
much more direct and useful ways of doing all that, but you may have
to throw away some of your existing thinking.

Anyhow, for debugging, I suggest starting from scratch, use the
userdata as your lua "object", not a table, and start implementing
from there. Once you've got it working, integrate back into your app.

Also, remember to call collectgarbage() to force a gc cycle, otherwise
you might have to wait a while, even for lua to exit, before gc
happens. Put a printf() in your __gc so you can watch the collection
happen.

Also, take a look at debug.getmetatable(), it will help you inspect
your userdata to verify it's metatable has a __gc.

Cheers,
Sam