Hi there! Things are a bit clrearer now, but I’m still having a bit to learn about how to manage resources. I am trying to expose data to lua functions for manipulation, but I don’t want lua to free the resources. I want to be able to allocate objects in C++, send them to lua and then continue using them in my C++ application. If I allocate the userdata in lua, lua should gc it when done.
Using a framework is nice i guess, but I want to learn a bit more about the inner workings before I use a tool.
The trick line here is this “Foo ** udata = (Foo **)lua_newuserdata(l, sizeof(Foo *));”
Notice that the userdata is a pointer. So the actual object allocated in C++ will never be GC’ed by Lua. If Lua loses references to the object, the Lua GC will deallocate the pointer — an integer
Lua’s runtime has no knowledge of the C runtime such as how the heap is arranged and what not, so Lua will never GC anything from C++. The GC can only deallocate what it allocated in the first place Remember, deallocating things in C++ must ultimately needs to calling “delete” or “free()”, and your Lua code can’t do that.
Therefore, in the above code, I allocate the object in C++ and the object always “stays in C++”
What about the idea of allocating the object itself in Lua? It is a bad idea because it is clumsy for C++ to obtain a pointer to that object. Remember that many GC implementations actually move the object in memory so if the C++ code saved a pointer to the object allocated in Lua, it may go kaboom when the pointer reference has been made obsolete by a compacting GC. What people do in languages like C# is to ask the GC not to move something (“pinning it”) – which makes it quite clumsy and makes GC’s algorithm very complicated.
So again the above should already satisfy your objective
I’m experimenting with a FooWrapper that wraps a shared_ptr, and it seems to solve the whole memory management problem. But I am not sure I want to use boost When lua decides to kill the LuaWrapper*, the destructor will dereference the shared_ptr and as long as i’ve got a reference in my c++ code, all is well.
This way I can create the same type in lua and c++ and not worry about it dieing all of a sudden.
It’s a robust solution, but not the leanest.
Thanks again. I’ve learnt alot from your code and comments. The web is littered with lua embedding tutorials that people write the moment the start to grasp this. It’s honestly a sickness of the web
This is great. My code is actually in C, but this code works perfectly well if I change Foo to a struct and use malloc and free. I’ve been stuck on this for about half a day. I just didn’t know enough about lua to do it from first principles. There was either really complicated C++ examples or really simple C ones without an instance variable. I don’t think its helped that the Lua API has changed in 5.2. I tried to modify some 5.1 examples to 5.2 but I wasn’t completely sure what I was doing. I like that you’ve written some comments explaining what things do. Its just not possible to work out whats going on if your not familiar with lua.