0

I have defined a python-c-api class, its real data structure is as follow:

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

Here is the destruction function, every time the python class is destructed, this function would be processed.

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
} 

Is it necessary to let this function destruct the C class? Maybe when destructing the python object, Self could be deleted in the memory, therefore, the _in_Handle would call the C destruction method automaticly. However, if _in_Handle would not be deleted, this destruction method would not be processed. Because the destruction method should not be called by twice or more times, I want to know whether it is necessary to call it artificially.

cainmagi
  • 21
  • 1
  • 5

1 Answers1

0

Yes, it is necessary to call the destruction function artificially.

In this example, if we define the destruction method of Testclass as:

.cpp

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

Then we do not call it in the destruction function of the PyClass which name is cclass. After that, write a .py like this:

.py

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

You will find that you could not receive the message from the destruction method of TestClass. In fact, if you do not define this method artificially, the C class would remain in the memory and take the memory space. Compare to this method:

typedef struct _C_CMISS_h{
    PyObject_HEAD
    TestClass _in_Handle;
}C_CMISS_h;

Using this method to define the data region is recommended:

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

Then you could use new and delete to controll your memory space artificially.

cainmagi
  • 21
  • 1
  • 5
  • You can call use placement new and call the destructor yourself with the first method. Also, the C++ class would not "remain in memory", it just wouldn't free any resources it holds. The `sizeof(TestClass)` memory in the `_C_CMISS_h` would be freed by the Python deallocation. – DavidW Jul 11 '17 at 16:35
  • @DavidW Thanks for your answer! Both of the methods can work. I think either of them is a good alternative. – cainmagi Jul 14 '17 at 14:05