我正在努力将Lua嵌入到C ++项目中,该项目在很大程度上依赖于一些遗留的C代码。我有几个关于垃圾收集和变量范围的问题。
以下是与以下问题相关的一些摘录:
/* C side */
typedef struct
{
/* fields */
} Element;
typedef struct
{
void * m_elems
unsigned int size;
} Container;
// C API for managing Container and Element
....
int allocContainer(Container*, unsigned int);
void freeContainer(Container*);
Element * getElemByIndex(unsigned int);
// C++ side
struct ElementWrapper
{
private:
Element m_elem;
public:
/* field accessors (NO modifiers) */
};
class ContainerWrapper
{
private:
ContainerWrapper m_cntnr;
public:
ContainerWrapper(int N); // allocates space for N elements
~ContainerWrapper();
// stack alloc'ed variable
ElementWrapper getElementAtIndexStackAllocated(unsigned idx) const;
// heap alloc'ed variable
ElementWrapper * getElementAtIndexHeapAllocated(unsigned idx) const;
};
-- Lua side
wrapper = Container:new(10)
for i =1,10 do
-- get the ith element
el_s = wrapper.getElementAtIndexStackAllocated(i)
el_h = wrapper.getElementAtIndexHeapAllocated(i)
-- do something with retrieved element ..
end
注意:我是故意的,不使用智能指针(如boost:shared_ptr),因为C库处理所有的内存分配/释放等,因为我不知道Lua垃圾收集器何时启动,所有的我向Lua公开的包装类(通过tolua ++),包含原始C样式指针作为私有成员。当Lua GC收集暴露的C ++类时,不会删除它们。这样,C库将在需要时自行删除mem - 并且没有悬挂指针的危险 - 如果我使用共享指针或其他一些带引用计数的智能指针可能会被混淆Lua GC活动(希望你得到主旨 - 虽然我知道这最后一点不是很清楚)。最重要的是,我使用原始ptrs是有充分理由的。
答案 0 :(得分:0)
在Lua中,不再引用的元素是垃圾收集(在适当的时候)。
这意味着,只要您覆盖它们,就会考虑el_h
和el_s
进行垃圾回收,您无需进行local
。
换句话说,el_h
= 1时,i
获取的对象将被标记为垃圾收集,当您将el_h
分配给您将获得的对象时i
= 2。
我假设tolua ++将处理metatables,以便每当对象被垃圾收集时调用析构函数,我从未使用它,因为我总是发现更容易手工编写C或C ++函数的绑定代码。
但是,如果tolua ++会为你扩展索引,我会感到惊讶,它不知道应该这样做。您应该将相同的参数传递给Lua中的wrapper.getElementAtIndexStackAllocated()
,而不是在C ++中。
请注意,我使用了“标记为垃圾收集”。垃圾收集发生的实际时间取决于不同的因素,一般来说,依赖于此并不是一个好主意。但是,您可以使用collectgarbage("collect")