Вграждане на 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++ glue управлява това вместо мен?

Забележка: Умишлено не използвам интелигентни указатели (като boost:shared_ptr), защото C библиотеката обработва цялото разпределение/освобождаване на памет и т.н. и тъй като не знам кога се задейства събирачът на боклук на Lua, всички класове обвивки, които аз изложете на Lua (чрез tolua++), съдържат необработени указатели в стил C като частни членове. Те не се изтриват, когато изложеният C++ клас се събира от Lua GC. По този начин библиотеката C ще изтрие mem, когато и когато е необходимо, сама - и няма опасност от висящи указатели - което може да е случаят, ако използвам споделени указатели или някакъв друг интелигентен указател с преброяване на референции, което може да се обърка от дейностите на Lua GC (надявам се, че схванахте същината - въпреки че знам, че последната част не е много ясна). В крайна сметка, използвам необработени ptrs по добра причина.


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