销毁PyCapsule对象

las*_*ash 5 c python cpython

根据文档,第三个参数PyCapsule_New()可以指定一个析构函数,我假设应该在解压缩时调用它.

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);

} 
Run Code Online (Sandbox Code Playgroud)

但是,当我实例化对象并删除它或退出Python控制台时,似乎没有调用析构函数:

>>> 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 $ 
Run Code Online (Sandbox Code Playgroud)

我的猜测是它与Py_BuildValue()返回对"胶囊"的新引用有关,删除时不会影响原始.无论如何,我将如何确保对象被正确销毁?

使用Python 3.4.3 [GCC 4.8.4](在linux上)

fis*_*000 0

Py_BuildValue("O", thingy)只会增加引用计数thingy并返回 \xe2\x80\x93 文档说它返回一个 \xe2\x80\x9cnew 引用\xe2\x80\x9d 但当你向它传递一个现有的PyObject*.

\n\n

如果您的 \xe2\x80\x93 问题中的这些函数,即 \xe2\x80\x93 都在同一翻译单元中定义,则可能需要声明析构函数static(因此其完整签名为static void mapDestroy(PyObject* capsule);)以确保Python API在调用析构函数时可以正确查找functions\xe2\x80\x99地址。

\n\n

\xe2\x80\xa6 你不必使用\xe2\x80\x99 函数static,只要析构函数\xe2\x80\x99s 在内存中的地址是有效的。例如,I\xe2\x80\x99ve 成功使用C++ 非捕获 lambda 作为析构函数,因为非捕获 C++ lambda 可以转换为函数指针;如果您想使用另一种更适合您的方式为您的胶囊析构函数获取和传递函数指针,请务必采用它。

\n