cython 使用 class 包装器指针

cython use class wrapper pointer

我是 cython 的新手,也许我缺少一些基本信息,所以请耐心等待。我想要做的是在 python 中创建一个 c++ 对象,修改它并 return 对象的指向 c++ 函数的指针。基本上我有:

// headers.h

class A {
    A();
    void modifyA()
}

class B {
    B();
    void useA(A *a);
}
# headers.pxd

cdef extern from "headers.h":
    cdef cppclass A:
        void modifyA()

    cdef cppclass B:
        void useA(A *a)
# PyA.pyx

cdef class PyA:
    cdef A *pa

    def __cinit__(self):
        self.pa = new A()

    def modifyA(self):
        self.pa.modifyA()

现在,据我所知,当我从 python 代码实例化 PyA 时,在 C++ 中创建了一个 A 对象,并且一个指针存储在新的 PyA 对象中。我想要做的是像这样使用该指针:

# PyB.pyx

cdef class PyB:
    cdef B *b

    def __cinit__(self):
        self.b = new B()

    def useA(self, pyA: PyA):
        self.b.useA(pyA.pa)

但它给了我“无法将 Python 对象转换为 'A *'”,我不明白为什么...我是否遗漏了什么?

Cython 中的“无法将 Python 对象转换为 'Something'”错误通常意味着 Cython 未检测 object/property 的类型,因此认为它将是 Python 对象,仅在运行时可用。

话虽如此,您必须确保 Cython 理解该类型。在您的特定情况下,您可以选择:

  • 只有一个 .pyx(合并两个 .pyx 文件),cython 能够直接确定 pyA.pa 的类型为 A*.
  • 声明一个“cython 头文件”或 .pxd 文件,它的工作方式与 C++ 中的 .h 文件非常相似,方法是声明对象类型、函数和 类。

第二种情况如下所示:

# PyA.pxd
cdef class PyA:
    cdef A *pa
# PyB.pyx
from PyA cimport PyA    # import the PyA class from PyA.pxd definition
cdef class PyB:
# [...]