【问题标题】:Embedding Lua in C++ mixed with C在与 C 混合的 C++ 中嵌入 Lua
【发布时间】:2011-02-01 08:52:32
【问题描述】:

我正在将 Lua 嵌入到 C++ 项目中,该项目严重依赖于一些遗留 C 代码。我有一些关于垃圾收集和变量范围的问题。

这里有一些与以下问题相关的sn-ps:

/* 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
  1. 变量 el_s 和 el_h 何时进行垃圾回收?
  2. 我是否需要对 el_s 和/或 el_h 使用“local”关键字来确保在“for”循环中的每次迭代结束时丢弃变量?
  3. C/C++ 世界中的索引从 0 开始,但 Lua 方面的索引从 1 开始 - 我需要在我的代码中注意这一点,还是 tolua++ 胶水代码为我管理这个?

注意:我故意不使用智能指针(如 boost:shared_ptr),因为 C 库处理所有内存分配/释放等,而且由于我不知道 Lua 垃圾收集器何时启动,所有我向 Lua 公开的包装类(通过 tolua++)包含原始 C 样式指针作为私有成员。当 Lua GC 收集暴露的 C++ 类时,它们不会被删除。这样,C 库将在需要时自行删除 mem - 并且没有悬空指针的危险 - 如果我使用共享指针或其他带有引用计数的智能指针可能会出现这种情况Lua GC 活动(希望你明白要点——尽管我知道最后一点不是很清楚)。归根结底,我使用原始 ptrs 是有充分理由的。

【问题讨论】:

    标签: c++ c lua


    【解决方案1】:

    在 Lua 中,不再引用的元素会被垃圾回收(在适当的时间)。 这意味着无论何时覆盖 el_hel_s 都会考虑进行垃圾回收,而无需将它们设为 local

    换句话说,当i = 1 时,您将为el_h 获得的对象将被标记为垃圾回收,当您将分配给el_h 时,您将获得i = 2 的对象.

    我假设 tolua++ 将处理元表,以便在对象被垃圾回收时调用析构函数,我从未使用过它,因为我总是发现手动为 C 或 C++ 函数编写绑定代码更容易。

    不过,如果 tolua++ 会为您缩放索引,我会感到惊讶,它不知道应该这样做。您应该在 Lua 中将相同的参数传递给 wrapper.getElementAtIndexStackAllocated(),就像在 C++ 中所做的那样。

    请注意,我使用了“标记为被垃圾收集”。垃圾收集发生的实际时间取决于不同的因素,一般来说,依赖于此并不是一个好主意。但是,您可以使用 collectgarbage("collect") 强制进行垃圾回收

    【讨论】:

      猜你喜欢
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-18
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多