[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