According to documentation, the third argument to PyCapsule_New()
can specify a destructor, which I assume should be called when the capsule is destroyed.
void mapDestroy(PyObject *capsule) {
lash_map_simple_t *map;
fprintf(stderr, "Entered destructor\n");
map = (lash_map_simple_t*)PyCapsule_GetPointer(capsule, "MAP_C_API");
if (map == NULL)
return;
fprintf(stderr, "Destroying map %p\n", map);
lashMapSimpleFree(map);
free(map);
}
static PyObject * mapSimpleInit_func(PyObject *self, PyObject *args) {
unsigned int w;
unsigned int h;
PyObject *pymap;
lash_map_simple_t *map = (lash_map_simple_t*)malloc(sizeof(lash_map_simple_t));
pymap = PyCapsule_New((void *)map, "MAP_C_API", mapDestroy);
if (!PyArg_ParseTuple(args, "II", &w, &h))
return NULL;
lashMapSimpleInit(map, &w, &h);
return Py_BuildValue("O", pymap);
}
However, when I instantiate the object and delete it or exit from Python console, the destructor doesn't seem to be called:
>>> a = mapSimpleInit(10,20)
>>> a
<capsule object "MAP_C_API" at 0x7fcf4959f930>
>>> del(a)
>>> a = mapSimpleInit(10,20)
>>> a
<capsule object "MAP_C_API" at 0x7fcf495186f0>
>>> quit()
lash@CANTANDO ~/programming/src/liblashgame $
My guess is that it has something to do with the Py_BuildValue()
returning a new reference to the "capsule", which upon deletion doesn't affect the original. Anyway, how would I go about ensuring that the object is properly destroyed?
Using Python 3.4.3 [GCC 4.8.4] (on linux)
The code above has a reference leak: pymap = PyCapsule_New()
returns a new object (its refcount is 1), but Py_BuildValue("O", pymap)
creates a new reference to the same object, and its refcount is now 2.
Just return pymap;
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With