0

Cluster と ClusterTree の 2 つの C++ クラスをラップしようとしています。ClusterTree には、Cluster オブジェクトをインスタンス化し、その参照を返すメソッド get_current_cluster() があります。ClusterTree は Cluster オブジェクトを所有し、C++ でその作成と削除を管理します。

Cluster を cython でラップして、PyCluster を作成しました。

PyCluster には、次の 2 つの作成方法が必要です。

1) 2 つの配列を渡す。これは、Python が削除を自動的に処理する必要があることを意味します (__dealloc__ を使用)
。 2) 生の C++ ポインター (ClusterTree の get_current_cluster() によって作成) を直接渡す。この場合、ClusterTree は基になるポインターを削除する責任を負います。

libcpp cimport bool から
libcpp.vector から cimport vector

"../include/Cluster.h" 名前空間 "Terran" からの cdef extern:
    cdef cppclass クラスター:
        Cluster(vector[vector[double]],vector[int]) + 以外

cdef クラス PyCluster:
    cdef クラスター* __thisptr
    __autoDelete = True

    def __cinit__(self, vector[vector[double]] data, vector[int] period):
        self.__thisptr = 新しいクラスター (データ、期間)  

    @クラスメソッド
    def __constructFromRawPointer(self, raw_ptr):
        self.__thisptr = raw_ptr
        self.__autoDelete = False

    def __dealloc__(self):
        self.__autoDelete の場合:
            del self.__thisptr

"../include/ClusterTree.h" 名前空間 "Terran" からの cdef extern:
    cdef cppclass ClusterTree:
        ClusterTree(vector[vector[double]],vector[int]) + 以外
        クラスター& getCurrentCluster()

cdef クラス PyClusterTree:

    cdef ClusterTree *__thisptr

    def __cinit__(self, vector[vector[double]] data, vector[int] period):
        self.__thisptr = 新しい ClusterTree(データ、期間)

    def __dealloc__(self):
        del self.__thisptr

    def get_current_cluster(self):

        cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster())
        return PyCluster.__constructFromRawPointer(ptr)

これにより、次の結果が得られます。

Cython ファイルのコンパイル エラー:
-------------------------------------------------- ----------
...
    def get_current_cluster(self):
        cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster())
        return PyCluster.__constructFromRawPointer(ptr)
                                                     ^
-------------------------------------------------- ----------

terran.pyx:111:54: 'Cluster *' を Python オブジェクトに変換できません

__init__ または @classmethods を cdef できないことに注意してください。

4

2 に答える 2

0

これは古い質問であることは知っていますが、最近Cythonと格闘した後、後世のために回答を投稿すると思いました。

コピー コンストラクターを使用して、既存の Cluster オブジェクトから新しい PyCluster オブジェクトを作成できるようです。

C コードでコピー コンストラクターを定義してから、Python クラス定義でコピー コンストラクターを呼び出します (この場合は、ポインターが渡されたとき) new。これは機能しますが、最善または最もパフォーマンスの高いソリューションではない場合があります。

于 2015-03-11T07:47:05.887 に答える