lua-users home
lua-l archive

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

> > some C function in your engine pushes a function (that 
> happens to be of C
> > type) on the LUA stack, lua_pcall() it, and this leaves a 
> full userdata on
> > the LUA stack as a result, from which you extract the pointer ?
> > If so, I think your full userdata can be collected anytime 
> you call LUA
> > again unless you lua_ref() it.
> I'll try to be a bit more accurate:
> 1) Main program M registers the C function A with Lua as 
> "func_a", the C 
> function B with Lua as "func_b"
> 2) M executes loadbuffer with string "x=func_a()" and pcalls it
> 3) Lua passes control to the C function A which creates a new 
> userdata of 
> size, sizeof(int) and sets the value to 42. It also saves the 
> pointer returned 
> by lua_newuserdata in the C variable y.
> 4) Lua assigns the new userdata to Lua variable x and passes 
> control back to M.
> 5) M executes loadbuffer with string "z=func_b()" and pcalls it
> 6) Lua passes control to the C function B which pushes the 
> value of y (a 
> pointer to userdata) on the Lua stack.
> The userdata pointed to by y cannot be garbage collected 
> since it is still 
> held by Lua variable x.
> 7) Lua assigns the userdata to the Lua variable z.
> 8) After these steps the Lua variables x and y are equal, and 
> if passed to 
> another C function registered with Lua and are interpreted as 
> pointers to ints 
> they should contain 42.
> My questions are 1) Is this recommended, or should setp 6 
> create a new 
> userdata of size sizeof(int) and store 42 in it.
> 2) If it is recommended then what lua_* function do I use to 
> push the userdata 
> pointer onto the stack. Is it lua_pushlightuserdata since 
> that seems to have 
> the correct signature.
> You can assume that there is no C program which will change 
> the value of a 
> userdata. Once it is initialised it will not be changed.

If you want some C function to receive z and change x by accessing the
memory location it points to, you need to do this, because if z is another
full userdata, it is in a different memory location. You could do something
else though: when x is created, store an entry in the registry where y is
the key and x the value: then instead of passing y to func_b, retrieve x
from y in the registry and pass this instead.
This also guarantees that your full userdata will never be collected,
because there is a reference in the registry (unless you store all such
references in a table with weak values, this table being kept in the

> Thank you,
> Steven Murdoch.