Cython - copy constructors

2019-05-07 09:08发布

问题:

I've got a C library that I'm trying to wrap in Cython. One of the classes I'm creating contains a pointer to a C structure. I'd like to write a copy constructor that would create a second Python object pointing to the same C structure, but I'm having trouble, as the pointer cannot be converted into a python object.

Here's a sketch of what I'd like to have:

cdef class StructName:
     cdef c_libname.StructName* __structname

     def __cinit__(self, other = None):
         if not other:
             self.__structname = c_libname.constructStructName()
         elif type(other) is StructName:
             self.__structname = other.__structname

The real problem is that last line - it seems Cython can't access cdef fields from within a python method. I've tried writing an accessor method, with the same result. How can I create a copy constructor in this situation?

回答1:

When playing with cdef classes, attribute access are compiled to C struct member access. As a consequence, to access to a cdef member of an object A you have to be sure of the type of A. In __cinit__ you didn't tell Cython that other is an instance of StructName. Therefore Cython refuses to compile other.__structname. To fix the problem, just write

def __cinit__(self, StructName other = None):

Note: None is equivalent to NULL and therefore is accepted as a StructName.

If you want more polymorphism then you have to rely on type casts:

 def __cinit__(self, other = None):
     cdef StructName ostr
     if not other:
         self.__structname = c_libname.constructStructName()
     elif type(other) is StructName:
         ostr = <StructName> other
         self.__structname = ostr.__structname


标签: cython