[Pyrex] C++ object construction/destruction

Lenard Lindstrom len-l at telus.net
Thu Jun 21 19:01:46 UTC 2007


Joel B. Mohler wrote:
> Here's a bit of a trick which I think might be of interest to people who wish 
> to use C++ from pyrex.  I apologize to the pyrex list if this is already 
> amply covered (I was unable to find searchable mailing list archives to 
> search for my possible redundancy.)
>
> Here's the situation.  I have a C++ class (I'll call it Foo) which I want to 
> wrap for access from python.  I have a choice.  I can initialize a pointer to 
> my object in the __new__ function in my python/pyrex object and delete in the 
> __dealloc__ or I can simply declare the object as member of the pyrex cdef'ed 
> class (not a pointer so as to save yourself a memory allocation):
>
> cdef class FooWrapper:
>     cdef Foo x
>
> This seems to work just fine ... as long as the constructor of Foo isn't too 
> exciting.  However, there's a very bad problem.  Neither the constructor or 
> destructor are called for Foo since the memory is allocated with malloc (or 
> PyMalloc or something).  So, you need to call the constructor and destructor 
> somehow.  The rest of this e-mail provides a simple way to do so.  Thanks to 
> David Harvey for pointing out this matter and helping with the solution even 
> though I was comforted by the fact that my code worked -- actually, in my 
> situation, I had a memory leak since the destructor wasn't called!
>
> Here's a link to a little C++ header file which declares 4 templated functions 
> which call C++ constructors and destructors both with and with-out 
> allocating/deallocating memory.  
> http://sage.math.washington.edu/home/jbmohler/patches/ccobject.h
> The main trick is that we need to call the constructor of Foo, but the memory 
> is already allocated.  An important nuance of the C++ new operator is 
> described here:
> http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc05cplr199.htm
>
> Declare these for pyrex:
> ####  foo.pxd
> cdef extern from "foo.h":
>     ctypedef struct Foo:
>         pass
>
>     # Some non-allocating versions
>     Foo* Foo_construct "Construct<Foo>"(void *mem)
>     void Foo_destruct "Destruct<Foo>"(Foo *mem)
>
>     # some allocating versions for completeness
>     Foo* Foo_new "New<Foo>"()
>     void Foo_delete "Delete<Foo>"(Foo *mem)
>
> ### foo.pyx
> cdef class FooWrapper:
>     def __new__(self):
>         Foo_construct(&self.x)
>
>     def __dealloc__(self):
>         Foo_destruct(&self.x)
>
>   

Nice. At first I had my misgivings since a C structure with a C++ class 
member becomes a C++ class itself, with both an automatically generated 
constructor and destructor. But of course both constructor and 
destructor are non-virtual, so no vtable or vtable pointer. I would be 
concerned about compiling code with rtti though.

-- 
Lenard Lindstrom
<len-l at telus.net>




More information about the Pyrex mailing list