我正在尝试包装两个C ++类:Cluster和ClusterTree。 ClusterTree有一个方法get_current_cluster(),它实例化一个Cluster对象,并返回对它的引用。 ClusterTree拥有Cluster对象,并在C ++中管理其创建和删除。
我用cython包装了Cluster,导致了PyCluster。
PyCluster应该有两种创建方式:
1)通过传入两个数组,这意味着Python应该自动处理删除(通过__dealloc__)
2)直接传入原始C ++指针(由ClusterTree的get_current_cluster()创建)。在这种情况下,ClusterTree承担删除基础指针的责任。
from libcpp cimport bool from libcpp.vector cimport vector cdef extern from "../include/Cluster.h" namespace "Terran": cdef cppclass Cluster: Cluster(vector[vector[double]],vector[int]) except + cdef class PyCluster: cdef Cluster* __thisptr __autoDelete = True def __cinit__(self, vector[vector[double]] data, vector[int] period): self.__thisptr = new Cluster(data, period) @classmethod def __constructFromRawPointer(self, raw_ptr): self.__thisptr = raw_ptr self.__autoDelete = False def __dealloc__(self): if self.__autoDelete: del self.__thisptr cdef extern from "../include/ClusterTree.h" namespace "Terran": cdef cppclass ClusterTree: ClusterTree(vector[vector[double]],vector[int]) except + Cluster& getCurrentCluster() cdef class PyClusterTree: cdef ClusterTree *__thisptr def __cinit__(self, vector[vector[double]] data, vector[int] period): self.__thisptr = new ClusterTree(data,period) def __dealloc__(self): del self.__thisptr def get_current_cluster(self): cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster()) return PyCluster.__constructFromRawPointer(ptr)
这导致:
Error compiling Cython file: ------------------------------------------------------------ ... def get_current_cluster(self): cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster()) return PyCluster.__constructFromRawPointer(ptr) ^ ------------------------------------------------------------ terran.pyx:111:54: Cannot convert 'Cluster *' to Python object
注意我不能cdef __init__或@classmethods。
答案 0 :(得分:1)
指针只能作为参数传递给cdef'd函数,而cinit必须被def'd。但提供一种类方法几乎的方式去了!
cdef Cluster* __thisptr
cdef bool __wrapped ## defaults to False
@staticmethod
cdef PyCluster wrap(Cluster* ptr):
cdef PyCluster pc = PyCluster([], []) ## Initialize as cheaply as possible
del pc.__thisptr ## delete the old pointer to avoid memory leaks!
pc.__thisptr = ptr
pc.__wrapped = True
return pc
答案 1 :(得分:0)
我知道这是一个古老的问题,但在我最近与Cython的斗争后,我以为我会为了后代而发布一个答案。
在我看来,你可以使用复制构造函数从现有的Cluster对象创建一个新的PyCluster对象。
在C代码中定义复制构造函数,然后使用new
在Python类定义中调用复制构造函数(在这种情况下,传递指针时)。这可行,但它可能不是最好或最有效的解决方案。