[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Userdata
- From: Sean Conner <sean@...>
- Date: Tue, 3 Jan 2012 00:43:22 -0500
It was thus said that the Great Dirk Laurie once stated:
> The Four Laws of a userdata:
>
> 1. The closest a full userdata ever gets to your C code is the Lua stack.
> 2. You can create a new userdata on the stack.
> 3. You can receive an old userdata on the stack.
> 4. There is no other way to return a userdata to Lua.
>
> You can check the registry type of a userdata on the stack, get its
> block address, modify its contents, push the block address as a light
> userdata — but you can't transform that light userdata back into a
> full one. Once it's off the stack, it is gone.
>
> Right?
I'm not so sure ...
typedef int foo__t; /* doesn't really matter */
int foo(lua_State *L)
{
foo__t *pfoo;
pfoo = lua_newuserdata(L,1);
luaL_getmetatable(L,FOO_TYPE);
lua_setmetatable(L,-2);
return 1;
}
int foo_full_to_light(lua_Stack *L)
{
foo__t *pfooa;
foo__t *pfoob;
pfooa = luaL_checkudata(L,1,FOO_TYPE);
pfoob = malloc(sizeof(foo__t));
memcpy(pfoob,pfooa,sizeof(foo__t));
lua_pushlightuserdata(L,pfoob);
return 1;
}
int foo_ligh_to_full(lua_Stack *L)
{
foo__t *pfooa;
foo__t *pfoob;
if (!lua_islightuserdata(L,1))
return luaL_error(L,"not a light user data");
pfooa = lua_touserdata(L,1);
pfoob = lua_newuserdata(L,sizeof(foo__t));
memcpy(pfoob,pfooa,sizeof(foo__t));
free(pfooa);
luaL_getmetatable(L,FOO_TYPE);
lua_setmetatable(L,-2);
return 1;
}
struct luaL_Reg foo_reg[] =
{
{ "foo" , foo } ,
{ "foo_to_light" , foo_full_to_light } ,
{ "foo_to_full" , foo_light_to_full } ,
{ NULL , NULL }
};
int luaopen_foo(lua_State *L)
{
luaL_register(L,"foo",foo_reg);
return 1;
}
--------------[ Lua code ]---------------------
foo = require "foo"
x = foo.foo()
y = foo.foo_to_light(x) -- dup x (full user data) to y (light user data)
x = nil -- remove x
z = foo.foo_to_full(y) -- dup y (light user data) to z (full user data)
------------[ end of line ]----------------------
Is there something I'm missing?
-spc (other than this being for Lua 5.1 ... )