问题描述
我想有几种在 Cython 中构造 cdef class
的方法,但我不知道如何使用带有扩展类的工厂函数,这些扩展类可以使用 .pxd 文件导出到其他模块。
Cython documentation 具有以下带有工厂函数的示例,当我编译它时,它按预期工作:
from libc.stdlib cimport malloc,free
# 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
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
# Extension class properties
@property
def a(self):
return self._ptr.a if self._ptr is not NULL else None
@property
def b(self):
return self._ptr.b if self._ptr is not NULL else None
@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
@staticmethod
cdef WrapperClass new_struct():
"""Factory function to create WrapperClass objects with
newly allocated my_c_struct"""
cdef my_c_struct *_ptr = <my_c_struct *>malloc(sizeof(my_c_struct))
if _ptr is NULL:
raise MemoryError
_ptr.a = 0
_ptr.b = 0
return WrapperClass.from_ptr(_ptr,owner=True)
但是,当我尝试将 cdef 声明分解为这样的 .pxd 文件时:
WrapperClass.pxd
ctypedef struct my_c_struct:
int a
int b
cdef class WrapperClass:
cdef my_c_struct *_ptr
cdef bint ptr_owner
cdef WrapperClass from_ptr(my_c_struct *_ptr,bint owner)
cdef WrapperClass new_struct()
WrapperClass.pyx
# cython: language_level=3
from libc.stdlib cimport malloc,free
cdef class WrapperClass:
"""A wrapper class for a C/C++ data structure"""
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
# Extension class properties
@property
def a(self):
return self._ptr.a if self._ptr is not NULL else None
@property
def b(self):
return self._ptr.b if self._ptr is not NULL else None
@staticmethod
cdef WrapperClass from_ptr(my_c_struct *_ptr,owner=True)
当我尝试编译时出现以下错误:
WrapperClass.pxd:9:30: Self argument (my_c_struct *) of C method 'from_ptr' does not match parent type (WrapperClass)
对于可以导入另一个模块的扩展,是否不能使用静态类作为“类方法”?此示例代码是我正在处理的一个更大项目的替代品,我希望以多种方式构建 cpp Cython 类,其中一些将使用 cpp 数据结构作为参数({{3} } 注释只能使用工厂函数完成)。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)