
这是我正在做的事情:
// Initially, the stack contains a table
class Foo { ... };
lua_pushstring(L, "my_userdata");
void* mem = lua_newuserdata(L, sizeof(Foo));
new (mem) Foo();
lua_settable(L, -3);
// Later:
lua_pushstring(L, "my_userdata");
lua_gettable(L, -2);
Foo *foo = (Foo*)lua_touserdata(L, -1);
lua_pop(L, 1);
// How long will this pointer be valid?
我最好在这里使用operator new和light userdata吗?
Lua的首席架构师在Lua-l mailing list上解决了这个问题:
Quote: Apr 18, 2006; Roberto Ierusalimschy
The caution is about strings, not about userdata (although we actually
did not say that explicitly in the manual). We have no intention of
allowing userdata addresses to change during GC. Unlike strings, which
are an internal data in Lua, the only purpose of userdata is to be used
by C code, which prefer that things stay where they are 🙂
您可以通过将其锚定在以下状态来控制用户数据的生命周期:
>在registry年
>作为uservalue与另一个物体的生命联系在一起
>作为全局存储在pseudo-index LUA_RIDX_GLOBALS的表中
有几个原因你可能比lightuserdata更喜欢完整的用户数据:
>完整的userdata可能有自己的uservalue和metatable(所有lightuserdata共享相同的metatable)
>通过__gc元方法完成
>用于处理userdata的几个便利API函数(luaL_newmetatable,luaL_setmetatable等)
从C中的类创建userdata的常用方法是使用pointer-to-pointer idiom:
class Foo { ... };
static int new_Foo(lua_State *L) {
// begin userdata lifetime
Foo **ud = static_cast<Foo **>(lua_newuserdata(L, sizeof *ud));
luaL_setmetatable(L, "Foo");
// begin C++ object lifetime
*ud = new Foo();
return 1;
}
// __gc metamethod
static int delete_Foo(lua_State *L) {
Foo **ud = static_cast<Foo **>(luaL_checkudata(L, 1, "Foo"));
// end C++ object lifetime
delete *ud;
// end userdata lifetime
return 0;
}
转载注明原文:c – Lua userdata指针的生命周期 - 乐贴网