使用 Cython 包装 C++ 类时处理指针

Posted

技术标签:

【中文标题】使用 Cython 包装 C++ 类时处理指针【英文标题】:Handling pointers when wrapping C++ class with Cython 【发布时间】:2017-03-02 11:44:22 【问题描述】:

我在使用 cython 处理指针时遇到问题。类的 cython 实现包含一个指向类 Person 的 C++ 实例的指针。这是我的.pyx 文件:

person.pyx

cdef class PyPerson:
    cdef Person *pointer

    def __cinit__(self):
        self.pointer=new Person()

    def set_parent(self, PyPerson father):
        cdef Person new_father=*(father.pointer)
        self.c_person.setParent(new_father)        

C++ 方法setParentPerson 对象作为参数。由于PyPerson 类的属性pointer 是指向Person 对象的指针,因此我认为可以使用*(PyPersonObject.pointer) 语法在*pointer 指向的地址处获取对象。但是,当我尝试编译它时,出现以下错误

 def set_parent(self, PyPerson father):
    cdef Person new_father=*(father.pointer)
                             ^
------------------------------------------------------------

person.pyx:51:30: Cannot assign type 'Person *' to 'Person'

有人知道我怎样才能到达指针地址处的对象吗? 当我在 C++ 程序中做同样的事情时,我没有收到任何错误。如果您想查看它,这是 C++ 类的实现:

person.cpp

Person::Person():parent(NULL)


Person::setParent(Person &p)
     parent=&p;

注意:由于涉及整个类的其他原因,我无法通过持有 Person 实例 (cdef Peron not_pointer) 来解决它。

【问题讨论】:

【参考方案1】:

我应该阅读有关在 Cython 中使用 C++ 的整个 cython 文档。对于不知道的人,解引用运算符* 不能在 Cython 中使用。相反,您需要从 cython.operator 模块导入 dereference。当你想访问指向地址的对象时,你应该写dereference(pointer)

具体来说,我的问题的答案是写cdef Person new_father=dereference(father.c_person)

【讨论】:

tks,这个问题困扰着我 *this【参考方案2】:

对此的另一种解决方案可能是索引到位置 0 处的指针以取消引用 Cython 中的指针。 例如,假设我们有一个 golden_ratio C double 和一个 p_double C 指针:

cdef double golden_ratio
cdef double *p_double

我们可以将golden_ratio’s 地址分配给p_double,使用地址运算符&:

p_double = &golden_ratio

我们现在可以使用我们的分配给golden_ratiop_double indexing-at-at-zero-to-dereference 语法:

p_double[0] = 1.618
print(golden_ratio)
# => 1.618

【讨论】:

以上是关于使用 Cython 包装 C++ 类时处理指针的主要内容,如果未能解决你的问题,请参考以下文章

Cython 中的 C++ 指针

在 Cython 中包装自定义类型 C++ 指针

如何在 python 包装中使用 unicode 字符串用于带有 cython 的 c++ 类?

Cython 和重载的 c++ 构造函数

在 cython 中处理默认参数

在 ipython 中使用 Cython 包装 C++ 标准库