开发者

Embedding Lua in C++ mixed with C

I am working on embedding Lua in a C++ project, which relies heavily on some legacy C code. I have a few questions regarding to garbage collection and variable scope.

Here are some snippets related to the questions that follow:

/* 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. when are variables el_s and el_h garbage collected?
  2. Do I need to use the 'local' keyword for el_s and/or el_h to make sure that variables are discarded at the end of each iteration in the 'for' loop?
  3. Indices start from 0 in C/C++ world, but 1 from Lua side - do i need to be aware of this in my code, or does tolua++ glue code manage this for me?

Note: I am intentionally, not using smart pointers (like boost:shared_ptr), because the C library handles all of the memory allocation/deallocation etc, and since I dont know when the Lua garbage collector kick in, all of the wrapper classes I expose to Lua (via tolua++), contain raw C style pointers as private members. They are not deleted when the exposed C++ class is harvested by the Lua GC. This way, the C library will delete the mem as and when needed, b开发者_运维百科y itself - and there is no danger of dangling pointers - which may be the case if I use shared pointers or some other smart pointer with reference counting which may get confused by the Lua GC activities (hope you get the gist - though I know this last bit is not very clear). Bottom line, I am using raw ptrs for a good reason.


In Lua, elements that are no longer referenced are garbage collected (at the proper time). This means that el_h and el_s will be considered for garbage collection whenever you will overwrite them, you don't need to make them local.

In other words, the object you'll get for el_h when i = 1 will be marked for being garbage collected when you will assign to el_h the object you'll get for i = 2.

I assume tolua++ will handle the metatables so that destructors are called whenever the object will be garbage collected, I've never used it as I always found easier to write binding code for C or C++ functions by hand.

I would be surprised, though, if tolua++ would scale the index for you, it has no clue it should do that. You should pass the same argument to wrapper.getElementAtIndexStackAllocated() in Lua that you would do in C++.

Note that I've used "marked for being garbage collected". The actual time the garbage collection will happen depends on different factors and, in general, is not a good idea to be dependant on this. However you can force a garbage collection using collectgarbage("collect")

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜