[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Pushing a UserData pointer?
- From: Chris Marrin <chris@...>
- Date: Mon, 16 May 2005 11:53:55 -0700
I have a C++ object that I want to access from Lua. So I made it a
userdata by overriding the new operator like this:
void*
Object::operator new(size_t size)
{
lua_State* L = getGlobalState();
void* ud = lua_newuserdata(L, size);
return ud;
}
This leaves the userdata on the stack, so my Object ctor fiddles with it
(gives it a common metatable and refs it so it doesn't get GC'ed). Then
it gets popped.
This all works fine and I now have a userdata object which has my C++
instance data. The problem is, I can't push the C++ "this" pointer onto
the Lua stack, at least not in any way that results in it looking like a
userdata. The only thing I can do is:
lua_pushlightuserdata(L, this);
and if I then call lua_gettable(), it will fail because you can't
gettable on a lightuserdata. But you can do this on a userdata as long
as its metatable has an __index function, which mine does.
What I need is something like:
lua_pushuserdata(L, this);
But such a thing does not exist. I can understand why. You don't want to
go pushing some random pointer and then expect Lua to try to access its
metatable and then crash! To solve this, I created a global table called
__objects, with weak values. The key to this table is the this pointer,
as a lightuserdata, and the value is the userdata. Making the values
weak will allow these objects to get collected even if they are in this
table. So now I can simply do this:
lua_pushstring(L, "__objects");
lua_gettable(L, LUA_GLOBALSINDEX);
lua_pushlightuserdata(L, this);
lua_gettable(-2);
lua_remove(-2);
and voila' I have the userdata on the stack. The problem is this is very
slow, requiring two table accesses and stack fiddling every time.
Am I missing something in the public API, or is there really no more
efficient way to move between C++ and Lua?
--
chris marrin ,""$,
chris@marrin.com b` $ ,,.
mP b' , 1$'
,.` ,b` ,` :$$'
,|` mP ,` ,mm
,b" b" ,` ,mm m$$ ,m ,`P$$
m$` ,b` .` ,mm ,'|$P ,|"1$` ,b$P ,` :$1
b$` ,$: :,`` |$$ ,` $$` ,|` ,$$,,`"$$ .` :$|
b$| _m$`,:` :$1 ,` ,$Pm|` ` :$$,..;"' |$:
P$b, _;b$$b$1" |$$ ,` ,$$" ``' $$
```"```'" `"` `""` ""` ,P`
"As a general rule,don't solve puzzles that open portals to Hell"'