3

使用C++lua 5.1luabind 0.7-0.81

尝试创建一个带有父级的 lua 类并将其存储在 luabind::object 中。

卢阿

class 'TestClassParent'
function TestClassParent:__init()
    print('parent init\n')
end
function TestClassParent:__finalize()
    print('parent finalize\n')
end

class 'TestClass' (TestClassParent)
function TestClass:__init()
    print('init\n')
    TestClassParent.__init(self)
end
function TestClass:__finalize()
    print('finalize\n')
end

C++

{
    luabind::object obj = luabind::call_function<luabind::object>(lua_state, "TestClass");
}
printf("before GC\n");
lua_gc(lua, LUA_GCCOLLECT, 0);
printf("after GC\n");

输出: GC 之后的
init
parent init
before GC

结果: obj 被销毁后,'TestClass' 实例在垃圾回收周期后仍然存在(不调用 __finalize 方法并且不释放内存)。它仅在程序退出时破坏。
如果我在没有父级的情况下使用类,垃圾会被正确收集。

如果我尝试使用采用策略(获取创建对象的所有权)

luabind::object obj = luabind::call_function<luabind::object>(lua_state, "TestClass")[luabind::adopt(luabind::result)];

我得到:

  • luabind 0.7 - 与没有采用策略的结果相同
  • luabind 0.81 - 崩溃并显示消息“您正在尝试使用 unregistrerd 类型”

如何在 C++ 中正确创建一个 lua 对象并获得它的所有权

4

2 回答 2

8

这是 0.8.1 中的一个已知错误;对最后一个构造对象的引用留在“超级”函数 upvalue 中。它已在 0.9-rc1 中修复:

http://github.com/luabind/luabind/commit/2c99f0475afea7c282c2e432499fd22aa17744e3

于 2009-12-22T13:40:21.843 回答
1

编辑:在 OP 更新之后,这个答案不再相关,不过我会把它挂在这里。Daniel Wallin 发布了正确答案

不是真正的答案,但我会丢失带有评论的格式

我无法复制这个。这是我使用的确切代码:

// initialization
lua_State* lua = lua_open();
luaL_openlibs(lua);
luabind::open(lua);
// declare class
luaL_loadstring(lua, 
    "class 'TestClass'\
     function TestClass:__init() print('init') end\
     function TestClass:__finalize() print('finalize') end");
lua_pcall(lua, 0, LUA_MULTRET, 0);
// instantiate
{
    luabind::object obj = luabind::call_function<luabind::object>(lua, "TestClass");
}
// collect
printf("Before GC collect\n");
lua_gc(lua, LUA_GCCOLLECT, 0);
printf("After GC collect\n");
lua_close(lua);

我得到的结果是:

init
Before GC collect
finalize
After GC collect

我正在使用 lua 5.1.4,luabind 0.81 和 VC8(又名 VS2005)SP1

于 2009-12-21T20:29:48.453 回答