Встраивание Lua в C ++, смешанное с C - PullRequest
3 голосов
/ 01 февраля 2011

Я работаю над внедрением 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 в качестве приватных членов.Они не удаляются, когда открытый класс C ++ собирается с помощью Lua GC.Таким образом, библиотека C сама удалит mem по мере необходимости, и при этом не будет опасности зависания указателей - что может быть в случае, если я использую общие указатели или какой-либо другой умный указатель со счетчиком ссылок, который может быть сбит с толкудействия Lua GC (надеюсь, вы понимаете суть - хотя я знаю, что последний момент не очень ясен).Итог, я использую сырые ptrs по уважительной причине.

1 Ответ

0 голосов
/ 01 февраля 2011

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...