Lua/Luabind: объекты, созданные объектами, остаются выделенными

У меня есть простой Lua скрипт

function TestFunction(Id)
    local Factory = TestParent();
    local ChildDirect = TestChild("DirectCall");
    local ChildFactory1 = Factory:CreateChild("Factory1");
    local ChildFactory2 = Factory:CreateChild("Factory2");

    result = Ret()
    return result
end

который использует два открытых объекта C++ (через luabind)

void TestParent::RegisterToLua(lua_State* lua)
{
  // Export our class with LuaBind
  luabind::module(lua) 
    [
        luabind::class_<TestParent>("TestParent")
            .def(luabind::constructor<>())
            .def("CreateChild", &TestParent::CreateChild)
    ];
}

void TestChild::RegisterToLua(lua_State* lua)
{
  // Export our class with LuaBind
  luabind::module(lua) 
    [
        luabind::class_<TestChild>("TestChild")
            .def(luabind::constructor<std::string>())
            .def("GetValue", &TestChild::GetValue)
    ];
}

я вызываю функцию

luabind::object obj = luabind::call_function< luabind::object >(LuaState, "TestFunction", IdParam);

if ( obj.is_valid() )
{
        ....
}

lua_gc(LuaState, LUA_GCCOLLECT, 0);

Во время вызова lua_gc уничтожаются только объекты Factory и ChildDirect. ChildFactory1 и ChildFactory2 остаются выделенными. Стек lua ​​остается сбалансированным (имеет то же значение — 5 — некоторые таблицы) после luabind::call_function.

В чем проблема ? Объекты, созданные Factory, остаются каким-то образом упомянутыми? Кем ?

Тело CreateChild

TestChild* TestParent::CreateChild(std::string strname)
{
    return new TestChild(strname);
}

Право собственности на новый созданный объект должно быть передано объекту lua и уничтожено, если ChildFactory1 или ChildFactory2 nil-ed или вне области видимости.


person vlg789    schedule 16.01.2014    source источник
comment
Просто догадка, но попробуйте вызвать lua_gc дважды подряд. Lua использует инкрементный сборщик мусора, который работает в течение определенного периода времени, поэтому вполне возможно, что только один вызов не выполняет полную сборку + завершение.   -  person Colonel Thirty Two    schedule 16.01.2014


Ответы (2)


adopt: используется для передачи права собственности через языковые границы.

module(L)
[
    def("create", &create, adopt(result))
];
person cprogrammer    schedule 16.01.2014

Вы должны вернуть интеллектуальный указатель (т.е. boost::shared_ptr) из вашей фабрики.

см.: LuaBind Документация # умный указатель

и обсуждение в документе по LuaBridge.

person Dmitry Ledentsov    schedule 16.01.2014