Встраивание Lua в C++, смешанное с C

Я работаю над внедрением 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
  1. когда происходит сбор мусора для переменных el_s и el_h?
  2. Нужно ли использовать ключевое слово local для el_s и/или el_h, чтобы убедиться, что переменные отбрасываются в конце каждой итерации в цикле for?
  3. Индексы начинаются с 0 в мире C/C++, но с 1 со стороны Lua - нужно ли мне знать об этом в моем коде, или склеивающий код tolua++ управляет этим для меня?

Примечание. Я намеренно не использую интеллектуальные указатели (например, boost:shared_ptr), потому что библиотека C обрабатывает все выделение/освобождение памяти и т. д., и поскольку я не знаю, когда включается сборщик мусора Lua, все классы-оболочки я предоставлять доступ к Lua (через tolua++), содержать необработанные указатели в стиле C в качестве закрытых членов. Они не удаляются, когда сборщик мусора Lua собирает открытый класс C++. Таким образом, библиотека C сама удалит mem по мере необходимости - и нет опасности оборванных указателей - что может быть в случае, если я использую общие указатели или какой-либо другой интеллектуальный указатель с подсчетом ссылок, который может запутаться действия Lua GC (надеюсь, вы уловили суть — хотя я знаю, что этот последний момент не очень ясен). Суть в том, что я использую необработанные PTR по уважительной причине.


person oompahloompah    schedule 01.02.2011    source источник


Ответы (1)


В Lua элементы, на которые больше нет ссылок, удаляются сборщиком мусора (в нужное время). Это означает, что el_h и el_s будут учитываться для сборки мусора всякий раз, когда вы их перезаписываете, вам не нужно делать их local.

Другими словами, объект, который вы получите для el_h, когда i = 1, будет помечен как сборщик мусора, когда вы назначите el_h объект, который вы получите для i = 2.

Я предполагаю, что tolua++ будет обрабатывать метатаблицы, поэтому деструкторы вызываются всякий раз, когда объект будет собираться мусором, я никогда не использовал его, поскольку мне всегда было проще писать код привязки для функций C или C++ вручную.

Я был бы удивлен, однако, если tolua++ будет масштабировать индекс для вас, он понятия не имеет, что должен это делать. Вы должны передать тот же аргумент wrapper.getElementAtIndexStackAllocated() в Lua, что и в C++.

Обратите внимание, что я использовал «отмечен для сбора мусора». Фактическое время сборки мусора зависит от разных факторов и, как правило, не стоит зависеть от этого. Однако вы можете принудительно выполнить сборку мусора, используя collectgarbage("collect")

person Remo.D    schedule 01.02.2011