我正在尝试包装两个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 .
2 回答
指针只能传递给cdef 'd functions as arguments, and cinit has to be def' d . 但提供一种类方法是 almost 的方法!
我知道这是一个古老的问题,但在我最近与Cython的斗争后,我想我会为了后代而发布一个答案 .
在我看来,您可以使用复制构造函数从现有的Cluster对象创建新的PyCluster对象 .
在C代码中定义复制构造函数,然后使用
new
在Python类定义中调用复制构造函数(在这种情况下,当传递指针时) . 这将起作用,尽管它可能不是最好或最高效的解决方案 .