python-c-api destruction函数中是否需要destuct一个c-class?

Is it necessary to destuct a c-class in the python-c-api destuction function?

我定义了一个python-c-apiclass,它的真实数据结构如下:

typedef struct _C_CMISS_h
{
    PyObject_HEAD             // == PyObject ob_base;
    TestClass _in_Handle;
}C_CMISS_h;

这里是销毁函数,每次pythonclass被销毁,都会处理这个函数

static void C_CMISS_Destruct(C_CMISS_h* Self){ //reload the destuction method
    /*Self->_in_Handle.~TestClass(); //destruct the C class*/
    Py_TYPE(Self)->tp_free((PyObject*)Self); //destruct this instance
} 

有必要让这个函数析构Cclass吗?可能在析构python对象时,内存中的Self会被删除,所以_in_Handle会自动调用C的析构方法。但是如果_in_Handle不会被删除,这个销毁方法就不会被处理。因为销毁方法不应该被调用两次或更多次,想知道是否需要人为调用。

是的,需要人为调用销毁函数

在这个例子中,如果我们定义Testclass的销毁方式为:

.cpp

TestClass::~TestClass(){
    cout << "CALL THE DESTRUCTION!!!!" << endl;
}

那我们就不要在名字为cclass的PyClass的析构函数中调用了。之后,像这样写一个.py:

.py

import Xdll
if __name__=='__main__':
    X = Xdll.cclass()
    print(X)
    X = 11
    print(X)

你会发现你收不到来自TestClass的销毁方法的消息。实际上,如果不人为定义这个方法,Cclass就会一直留在内存中,占用内存space。与此方法比较:

typedef struct _C_CMISS_h{
    PyObject_HEAD
    TestClass _in_Handle;
}C_CMISS_h;

推荐使用此方法定义数据区域:

typedef struct _C_CMISS_h{
    PyObject_HEAD
    TestClass *_in_Handle;
}C_CMISS_h;

那么你可以用newdelete来人为地控制你的记忆space