2

次の C++ クラスがあります。

.H

class ALabSet: public LabSet {
public:
    PyObject *m_obj;

    ALabSet(PyObject *obj);

    virtual ~ALabSet();

    PyObject *GetPyObj();

};

.CPP

ALabSet::ALabSet(PyObject *obj): LabSet() {

    this->m_obj = obj;
    // Provided by "cyelp_api.h"
    if (import_cyelp()) {
    } else {
        Py_XINCREF(this->m_obj);
    }

}


ALabSet::~ALabSet() {
    Py_XDECREF(this->m_obj);
}


PyObject *ALabSet::GetPyObj() {
    return this->m_obj;
}

Cython で次のように公開しました。

cdef extern from "adapter/ALabSiteSetsManager.h" namespace "elps" :
    cdef cppclass ALabSet:
        ALabSet(PyObject *)

        PyObject *GetPyObj()



cdef class PyLabSet:
    cdef ALabSet *thisptr

    def __cinit__(self):
       self.thisptr = new ALabSet(<PyObject *>self)

    def __dealloc__(self):
       print "delete from PY !"
       if self.thisptr:
           del self.thisptr

私の問題は、デストラクタを Python から呼び出す方法がわからないことです。以下はまったく何もしません:

a_set = PyLabSet()
del a_set

Web 上で同様の問題を見つけることができません。ここで私に近づいているという考えを持っている人はいますか?

参照カウント管理について何かが足りない、または...

どうもありがとう

4

1 に答える 1

5

del a_setオブジェクト (ローカル変数) への参照を削除します。C++ オブジェクトには、まだ別の参照があります。これは参照サイクルとして知られています。サイクル GCは、しばらくするとこれを収集できます。ただし、これがいつ発生するか (または発生したとしても) の保証はないため、これに依存するべきではありません1

たとえば、__del__特別なメソッドを持つ純粋な Python オブジェクトを含む参照サイクルは、まったく解放されないように文書化されています。

バージョン 3.4 で変更: PEP 442 に従って、メソッドを持つオブジェクト__del__()は終了しgc.garbageなくなりました。

Cython の の実装がこの動作を__dealloc__トリガーするかどうかはわかりませんが、前に概説したように、とにかく破壊は決定論的ではありません。何らかのリソース (たとえば、Python オブジェクト、ファイル、接続、ロックなどではないメモリのブロック) を解放したい場合は、明示的な方法を手動で公開する必要があります (closeさまざまなメソッドを参照)。オブジェクト)。コンテキスト マネージャーは、これを行うクライアント コードを簡素化できます。

免責事項: これはほとんどすべて CPython 固有のものです。

1 GC を、到達不能なオブジェクトを破壊するものではなく、無限のメモリの可用性をシミュレートする抽象化と考える人もいます。このアプローチでは、破壊が決定論的ではなく、保証さえされていないことが明らかになります。

于 2013-04-12T15:12:38.883 に答える