在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
1 如何封装c++的指针
对于c++对象的lua包装,我们可以使用 template<typename T> T data; class CObject { public: int v[10]; typedef luaUserdataWrapper<CObject*> luaObject; 这样就可以在c代码中,按照如下方法向lua中添加生成CObject的对象的C函数: int NewObject( lua_State* L ) { luaObject* wrapper = (luaObject*) lua_newuserdata( L, sizeof(luaObject) ); wrapper->data = new CObject; return 1; lua_newuserdata函数把wrapper存放在栈顶位置,作为NewObject的返回值。 wrapper的生存期由lua负责,而wrapper->data的生命期则由程序员自己负责。 在lua代码中的使用方法是: obj = NewObject() --调用C函数
2 使用metatable 如果此时我们想在lua中使用如下语法: obj[5]=20 value = obj[5] 则需要我们为luaObject添加metatable属性。 步骤1: 在lua代码中的普通表,不能作为userdata的metatable。必须使用luaL_newmetatable创建的表才能作为userdata的metatable。 在openlib函数中,添加一个userdata 的 metatable表, int OnOpenlib( lua_State* L ) { ... luaL_newmetatable( L, “ObjectMetatable"); } luaL_newmetatable把新创建的表放在栈顶。 注意:新创建的ObjectMetatable表仅在栈中被声明,并没有加入到lua代码中。如果在以后的lua代码中使用ObjectMetatable.__index等操作,会提示ObjectMetatable:a nil value。 步骤2: 这是我们重写上面的New方法。 int NewObject( lua_State* L ) { luaObject* wrapper = (luaObject*) lua_newuserdata( L, sizeof(luaObject) ); wrapper->data = new CObject; luaL_getmetatable( L, ”ObjectMetatable“); return 1; 这样我们就为新生成的luaObject对象添加metatable。 luaL_getmetatable( L, ”ObjectMetatable“)获取ObjectMetatable表,并放入栈顶。 lua_setmetatable( L, -2 )则把新生成的userdata的metatable设置为ObjectMetatable。 步骤3: value = obj[5]的取下标操作对应的是__index域,而 obj[5]=2;对应的是__newindex域。 所以我们需要添加ObjectMetatable的__index,__newindex域。 我们重写int OnOpenlib( lua_State* L )方法 int OnOpenlib( lua_State* L ) { ... luaL_newmetatable( L, “ObjectMetatable"); lua_pushstring( L, "__index" ); lua_pushstring( L, "__newindex" ); lua_rawset( L, -3 ); // ObjectMetatable.__newindex = GetHorizonValue } GetValue 与SetValue 是自定义的C函数,可以不用被注册到lua代码中。 在lua中调用 v=obj[5] 时,会触发元函数metatable.__index,obj、5会被依次入栈。 所以GetValue方法我们可以写为 int GetValue(lua_State* L) { luaL_checktype(L, -1, LUA_TNUMBER); luaObject* wrapper = (luaObject*) lua_touserdata(L, -2); ASSERT( wrapper->data != NULL ); int index = (int)(float)lua_tonumber(L, -1); int value = wrapper->data.v[index]; lua_pushnumber( L, value ); return 1; } |
请发表评论