views:

377

answers:

3

Using C++, lua 5.1, luabind 0.7-0.81

Trying to create a lua class with parent and store it in a luabind::object.

Lua

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");

Output:
init
parent init
before GC
after GC

Result: After obj is destroyed, 'TestClass' instance is still alive after garbage collection cycle (finalize method is not called and memory is not freed). It's destroying only on program exit.
**Moresome
if I use class without parent, garbage is collected correctly.

If I try to use adopt policy (to take ownership of created object)

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

I get:
* in luabind 0.7 - same result as without adopt policy
* in luabind 0.81 - crash with message "you are trying to use an unregistrerd type"

How can I correctly create a lua object in C++ and take it's ownership?

Thank you.

+1  A: 

Edit: after OP's update, this answer is no longer relevant, I'll leave it hanging here though. Daniel Wallin posted the correct answer

not really an answer, but I'd lose the formatting with a comment

I cannot reproduce this one. Here's the exact code I use:

// 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);

And the result I get is:

init
Before GC collect
finalize
After GC collect


I'm using lua 5.1.4, luabind 0.81 with VC8 (aka VS2005) SP1

sbk
Thank you very much for test. You're right. My description of a problem was not correct. It's actual only when class has a parent. I've updated a description in main post.
kFk
+4  A: 

This is a known bug in 0.8.1; a reference to the last constructed object is left in the "super" function upvalue. It has been fixed in 0.9-rc1:

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

Daniel Wallin
Is this about problem described here - http://stackoverflow.com/questions/1946465/luabind-class-deriving-problem-memory-leak ?
kFk
yes, this is the same bug.
Daniel Wallin
A: 

Problem is not in luabind::object. It's in class derivation. But problem is not solved yet. Please see corresponding question - http://stackoverflow.com/questions/1946465/luabind-class-deriving-problem-memory-leak

kFk