如何用Lua C API创建含Player Userdata的表?元表绑定异常求助
问题分析与修复
你的问题根源是设置元表时的栈索引错误,导致把PlayerMetaTable误绑定到了外层的PlayerList表上,而不是每个userdata元素。同时代码里的index变量未初始化,也会导致索引异常。
错误代码问题点
在Player::ToList的循环中:
luaL_getmetatable(L, "PlayerMetaTable"); lua_setmetatable(L, -4); // 这里索引错误!
此时Lua栈的结构(从栈底到栈顶)是:[目标table, 索引值index, userdata, PlayerMetaTable],lua_setmetatable需要传入要绑定元表的对象的栈索引——也就是userdata的位置-2(栈顶是元表,往上数第二个就是userdata),而你写的-4指向的是最开始创建的目标table,这就把元表错误地绑定给了外层的PlayerList,而不是每个userdata元素。
另外循环里的index变量未初始化,需要添加初始化逻辑(Lua表通常从1开始索引,如果你要兼容0索引也可以设为0)。
修复后的代码
int Player::ToList(lua_State* L) { lua_newtable(); GameLogic* gameLogic = global::get_game_logic(); int index = 1; // 或者根据需求设为0,对应Lua里的索引 for (auto it = gameLogic->PlayerList.begin(); it != gameLogic->PlayerList.end(); ++it) { lua_pushinteger(L, index); auto p = lua_newuserdata(L, sizeof(NativePlayer)); new (p) NativePlayer(); p->data = *it; luaL_getmetatable(L, "PlayerMetaTable"); lua_setmetatable(L, -2); // 修正索引,绑定到当前userdata lua_settable(L, -3); index++; // 索引自增 } return 1; }
验证结果
修复后运行你的测试Lua代码,输出会符合预期:
PlayerMetaTable: 000002607203F590 PlayerMetaTable: 0000026079E901D8 PlayerMetaTable: 0000026079EA1A08 table: 000002607203F7FF
内容的提问来源于stack exchange,提问作者Sio
相关产品推荐
相关产品推荐

