gpt4 book ai didi

c++ - C(++) 和 Lua 清理内存

转载 作者:行者123 更新时间:2023-11-28 07:40:28 24 4
gpt4 key购买 nike

我在我正在编写的应用程序中使用 Lua 的 C API,我试图确定我使用它的方式是否留下了一些悬空指针(指向指针)。

假设我在 C++ 中有一个树状结构(实际上是类)

struct Leaf
{
DoSomeLeafStuff();
List<Leaf*> Children;
};

class Tree
{
public:
Tree() { };
virtual ~Tree()
{
/* iterate over Children and delete them */
};

void DoSomeTreeStuff();
Leaf getRoot() const { return _root; }

private:
Leaf* _root;
};

-- 假设 tree 已经创建并包含数据,我在 Lua 中这样使用它:

local root = tree:getRoot()
root:DoSomeLeafStuff()

现在我的 Lua 的 getRoot() C 实现看起来像这样:

int LuaStuff::TreeGetRoot(lua_State* L)
{
Tree* tree = *(Tree**)luaL_checkudata(L, 1, "MyStuff.Tree");

if (tree != NULL && tree->getRoot() != NULL)
{
int size = sizeof(Leaf**);
*((Leaf**)lua_newuserdata(L, size)) = tree->getRoot(); // allocate a pointer to a pointer
lua_setmetatable(L, "MyStuff.Leaf");
}
else
{
lua_pushnil(L);
}

return 1;
}

经过一些故障排除后,我能够让我的 Tree 和 Leaf 对象在您期望的时候释放。但到目前为止,我还没有找到一种令人信服的方式(至少对我而言)指针指针正在被清理。

我的问题是:我可以安全地假设由 Lua 的 lua_newuserdata() 分配的内存会被 Lua 的垃圾收集自动清理吗?

最佳答案

我正在做类似的事情,将我自己的对象包装在 Lua 中。我就是这样做的:

/*part of the functon, buffer_s is a structure holding pointer 
to the real object and some other fields (like who actually created the object)
*/
buffer_s* b = (buffer_s*) lua_newuserdata(L, sizeof(buffer_s));
b->ptr = new buffer;
b->origin = FROM_LUA;
luaL_getmetatable(L, "buffer");
lua_setmetatable(L, -2);

现在,在初始化库时我也做这样的事情:

luaL_newmetatable(L, "buffer");  //create metatable
lua_pushcfunction(L,lua_buffer_delete); //push Lua compatible "destructor"
lua_setfield(L, -2, "__gc"); //place it in the metatable under __gc index

lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");

luaL_register(L, NULL, maps_buffer_m);

现在 Lua 将在释放(通过 GC)对象之前调用 __gc 元方法。您可以使用它进行清理。

我是这样做的(部分功能):

if (b->origin == FROM_LUA)
{

delete b->ptr; //delete the object
b->origin = PTR_INVALID; //and mark it as invalid
b->ptr = NULL;
lua_newtable(L);
lua_setmetatable(L, 1); //set empty metatable, it's not buffer any more
return 0;
}

希望对你有帮助:)

您可以考虑使用 tolua++ 或 swig 来自动执行绑定(bind)过程。它将节省大量时间,并且可能会以正确的方式处理对象的创建和删除。

关于c++ - C(++) 和 Lua 清理内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15924715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com