以下代码是将C ++类绑定到Lua。
void registerPerson(lua_State *lua, Person *person)
{
//We assume that the person is a valid pointer
Person **pptr = (Person**)lua_newuserdata(lua, sizeof(Person*));
*pptr = person; //Store the pointer in userdata. You must take care to ensure
//the pointer is valid entire time Lua has access to it.
if (luaL_newmetatable(lua, "PersonMetaTable")) //This is important. Since you
//may invoke it many times, you should check, whether the table is newly
//created or it already exists
{
//The table is newly created, so we register its functions
lua_pushvalue(lua, -1);
lua_setfield(lua, -2, "__index");
luaL_Reg personFunctions[] = {
"getAge", lua_Person_getAge,
nullptr, nullptr
};
luaL_register(lua, 0, personFunctions);
}
lua_setmetatable(lua, -2);
}
以上代码来自对此question的回答。它将C ++类(Person)绑定到Lua。正如你所看到的,这个函数
创建新的用户数据并将其推送到堆栈顶部。将人物指针存储在用户数据中。
使用名为“PersonMetaTable”的luaL_newmetatable创建一个元表,到目前为止,metatable应位于堆栈的顶部。
根据文档,lua_pushvalue
函数将给定索引处的元素复制到堆栈顶部。但是在这里,使用参数-1调用函数,我认为复制metatable(因为它位于堆栈的顶部),我是否正确?
为什么要复制metatable?这条线的目的是什么?
lua_pushvalue(lua, -1);
答案 0 :(得分:2)
lua_setfield
从堆栈中弹出指定的值,因此您需要lua_pushvalue
复制metatable引用,以便在设置__index
表时不会丢失它。
Begin: [Person*, metatable]
lua_pushvalue: [Person*, metatable, metatable] <- metatable duplicated and pushed onto stack
lua_setfield: [Person*, metatable] <- metatable duplicate is popped. metatable.__index = metatable
lua_setmetatable: [Person*] <- metatable is popped. getmetatable(Person*) = metatable