Cython 构造函数在 .pxd 文件中重载错误:工厂函数的“C 方法的自参数与父类型不匹配”

问题描述

我想有几种在 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 (将#修改为@)