我有以下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

我在网上找不到类似的问题。你们中有人有在这里出现过的想法吗?

我缺少有关引用计数管理的信息,或者...

非常感谢

最佳答案

del a_set删除对对象的引用(局部变量)。 C++对象中还有另一个引用。这称为引用周期。循环GC可能会在一段时间后收集此信息。但是,不能保证何时发生这种情况(如果是,甚至是),因此您不应该依赖它。

例如,包含纯Python对象的引用循环以及 __del__ 特殊方法are documented根本不会被释放:



我不知道Cython's implementation of __dealloc__ 是否会触发此行为,但是如前所述,销毁无论如何都不是确定性的。如果您要释放某些资源(例如,不是Python对象的内存块,文件,连接,锁等),则应公开一种明确的手动方式(请参见的close方法)各种对象)。上下文管理器可以简化客户端代码。

免责声明:几乎所有这些都是CPython特定的。

1有些人更喜欢将GC视为模拟无限内存可用性的抽象,而不是破坏无法访问的对象的抽象。通过这种方法,很明显破坏不是确定性的,甚至无法保证。

关于c++ - 删除对象时无法调用__dealloc__,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15974561/

10-11 22:55
查看更多