lua-users home
lua-l archive

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

2009/10/12 Jerome Vuarand <>
2009/10/12 liam mail <>:
> Whilst integrating C++ with Lua which enables the passing of C++ objects to
> Lua, calling methods, operators and vice versa I have encountered a problem
> with my current implementation. I use the method with is described on the
> wiki entitled Luna and which is also described in many other publications
> such as Game Programming Gems.
> The crux of my problem is that a new user data is only created when an
> object is currently not alive in Lua, when it is the pointer which was
> returned when the lua_newuserdata was created is pushed onto the stack using
> lua_pushlightuserdata and has it's metatable attached. This metatable
> defines the functions to be called for the operators such as __eq and __le;
> yet a lightuserdata is only equal to itself and does not look at the
> metatable to see if the operator is defined for the type, whilst it does
> look at the metatable for methods.
> Is there a way whilst still using the operators instead of say a le function
> (obj:le(rhs)) to accomplish this, or is using this type of function for the
> operator or using a table to represent the data the only method. Ie. is
> there a way to trick Lua into looking at the metatable of the lightuserdata
> for the operators without modifying the source of Lua itself?

Your first paragraph is a little confusing. I'm not sure what you did
exactly, and what userdata is full or light.

Light userdata are not meant to represent objects, but rather as a
convenience to pass C values around. If you have a C object that you
want to manipulate from Lua you should embed them in a full userdata.
You cannot push a full userdata. What you can do however is associate
a userdata with its address in some table (e.g. the registry), and
from the address you can push back the full userdata with a table
indexing operation (lua_gettable).

Sorry for the confusion I will try to explain again :)
Say for example a C++ class instance is pushed to Lua twice for a Lua function parameters. The first time it is detected that the instance is not currently valid in Lua and therefore a full userdata is created and the returned pointer is stored to enable the validity check and also to allow it being exchanged again. When the same instance is passed the second time it is detected that the instance is valid in Lua,  the pointer instance returned by the creating of the full user data is pushed onto the stack and the types metatable is associated with the light user data.
This enables methods to be called on the light user data via a lookup in the metatable yet fails on the operators.

Are you suggesting that the second time it is pushed the pointer returned from creating the full user data is pushed onto the stack then lua_gettable is called and this will enable the type to be seen as a full user data? If I do this is there still a need to attach the types metatable to the table pushed onto the stack via lua_gettable or should it be valid?