IMPORTANT UPDATE: reproducible example here
I have code similar to one in documentation, so that the class is created from pointer. It works perfectly, when both class definition and class instance creation are in the same file.
main.pyx:
cdef some_type * ptr_to_wrapped_type = <some_type *>malloc(sizeof(some_type))
#next part from documentation
cdef class WrapperClass:
"""A wrapper class for a C/C++ data structure"""
cdef my_c_struct *_ptr
cdef bint ptr_owner
@staticmethod
cdef WrapperClass from_ptr(my_c_struct *_ptr, bint owner=False):
"""Factory function to create WrapperClass objects from
given my_c_struct pointer.
Setting ``owner`` flag to ``True`` causes
the extension type to ``free`` the structure pointed to by ``_ptr``
when the wrapper object is deallocated."""
# Call to __new__ bypasses __init__ constructor
cdef WrapperClass wrapper = WrapperClass.__new__(WrapperClass)
wrapper._ptr = _ptr
wrapper.ptr_owner = owner
return wrapper
...
data = WrapperClass.from_ptr(ptr_to_wrapped_type, owner=True)
What I want is to move class definition into separate file and import it in main. This is also described in docs and that's what I have:
wrapper.pxd:
# Example C struct
ctypedef struct my_c_struct:
int a
int b
cdef class WrapperClass:
"""A wrapper class for a C/C++ data structure"""
cdef my_c_struct *_ptr
cdef bint ptr_owner
wrapper.pyx(class definition from docs):
from libc.stdlib cimport malloc, free
cdef class WrapperClass:
"""A wrapper class for a C/C++ data structure"""
cdef my_c_struct *_ptr
cdef bint ptr_owner
def __cinit__(self):
self.ptr_owner = False
def __dealloc__(self):
# De-allocate if not null and flag is set
if self._ptr is not NULL and self.ptr_owner is True:
free(self._ptr)
self._ptr = NULL
@staticmethod
cdef WrapperClass from_ptr(my_c_struct *_ptr, bint owner):
"""Factory function to create WrapperClass objects from
given my_c_struct pointer.
Setting ``owner`` flag to ``True`` causes
the extension type to ``free`` the structure pointed to by ``_ptr``
when the wrapper object is deallocated."""
# Call to __new__ bypasses __init__ constructor
cdef WrapperClass wrapper = WrapperClass.__new__(WrapperClass)
wrapper._ptr = _ptr
wrapper.ptr_owner = owner
return wrapper
...
And finally in main.pyx:
cdef some_type * ptr_to_wrapped_type = <some_type *>malloc(sizeof(some_type))
from wrapper cimport WrapperClass
data = WrapperClass.from_ptr(ptr_to_wrapped_type, owner=True)
Unfortunately, at compilation I get an Error:
data = WrapperClass.from_ptr(ptr_to_wrapped_type, owner=True)
^
------------------------------------------------------------
Cannot convert 'some_type *' to Python object
What is wrong?
@staticmethodfunction for yourWrapperClasscalledfrom_ptr?wrapper.new_var = _ptr.band of course I addedcdef int * new_varat the beginning of the class