【发布时间】:2014-06-13 12:06:47
【问题描述】:
我的 touserdata 和 newuserdata 出现了一些意想不到的问题,传递给 C++ 的数据与我创建 userdata 时存储的数据不同,下面我有与创建相关的所有函数以及我创建的函数正在打电话(
我用这个 lua 代码创建我的头像 avatar = avatar_create("hero1") 在 c++ 中是这样的
int LuaObjectFactory::createAvatar(lua_State* L){
auto avatar = new Avatar(lua_tostring(L, 1)); // 0x011afd20
auto userdata = Util::luaP_newuserdata<Avatar>(L, avatar); // 0x011a4a18
luaP_getScenes(L)->getActiveScene()->addEntity(avatar);
Util::luaP_setmetatable(L, Avatar::lGetMetatable());
return 1;
}
template<typename T> T** luaP_newuserdata(lua_State* L, T* data){
T** o = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
// Does not copy the data, only remembers reference to it
*o = data;
return o;
}
inline void luaP_setmetatable(lua_State* L, const string& metatable){
luaL_getmetatable(L, &metatable[0]);
lua_setmetatable(L, -2);
}
template<typename T> T* luaP_touserdata(lua_State* L, int idx){
return *static_cast<T**>(lua_touserdata(L, idx));
}
然后我尝试用这个 lua 代码调用 Avatar 的函数
avatar = avatar_create("hero1")
avatar:setPosition(12, 10)
avatarPos = avatar:getPosition()
调用这两个函数
template<typename T> static int lGetPosition(lua_State* L){
auto p = Util::luaP_touserdata<T>(L, 1); // 0x008ff0d8
auto v = p->getPosition();
lua_pushnumber(L, v.x);
lua_pushnumber(L, v.y);
return 0;
}
template<typename T> static int lSetPosition(lua_State* L){
auto p = Util::luaP_touserdata<T>(L, 1); // 0x008ff0d8
auto v = Math::Vector2(static_cast<int>(lua_tonumber(L, 2)),
static_cast<int>(lua_tonumber(L, 3)));
p->setPosition(v);
return 0;
}
我注释了我尝试调试时返回的内存地址,luaP_touserdata 返回相同的地址,尽管我在 0x008ff0d8 上设置的值在我稍后去获取它们时已被删除
我注意到的其他一点是,0x008ff0d8 的地址是一个指向指向 0x008ff0d8 的指针的指针。
【问题讨论】:
-
您能否检查(使用
lua_gettop())在Util::luaP_newuserdata<Avatar>调用和Util::luaP_setmetatable调用LuaObjectFactory::createAvatar之后的Lua 堆栈元素的数量?Util::luaP_touserdata<T>的实现也可能是相关的...... -
new Avatar后栈返回1,newuserdata后栈返回2,setmetatable后栈返回3,我在上面的setmetatable中添加了代码
-
然后在
return 1;之前添加一个lua_pop(L, 1);。在luaP_newuserdata和return 1之间的某个地方,一个新元素被推入堆栈(luaP_setmetatable函数看起来不错,我怀疑luaP_getScenes)。这个元素被返回到 Lua 而不是你的用户数据。 -
我实际上是在查看 luaP_getScenes 调用的函数后自己发现的,我希望 lua_touserdata 返回并从堆栈中删除,但事实并非如此。指针现在正确了,谢谢