2016-09-03 2 views
5

documentation에 따르면 세 번째 인수 인 PyCapsule_New()은 소멸자를 지정할 수 있습니다. 소멸자는 캡슐이 소멸 될 때 호출해야한다고 가정합니다. 나는 개체를 인스턴스화과 파이썬 콘솔에서 출구를 삭제할 때PyCapsule 객체 삭제

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

} 

그러나, 소멸자는 호출하지 않는 것 :

>>> 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() 
[email protected] ~/programming/src/liblashgame $ 

내 생각 엔 그것은 함께 할 수있는 뭔가가 있다는 것입니다 Py_BuildValue()은 삭제시 원본에 영향을주지 않는 "캡슐"에 대한 새 참조를 반환합니다. 어쨌든, 나는 그 물체가 적절하게 파괴되었는지 어떻게 알 수 있을까요? (리눅스에서) 파이썬 3.4.3 [GCC 4.8.4]를 사용하여

답변

0

Py_BuildValue("O", thingy) 단지 thingy에 대한 refcount가를 증가하고 반환합니다 - 워드 프로세서 그것은 "새로운 기준"을 반환하지만이 아니라고 말한다 합격하면 실제로 PyObject*이됩니다.

귀하의 이러한 기능 (질문에있는 기능)이 모두 동일한 번역 단위에 정의되어있는 경우 소멸자 기능은 static (완전한 서명이므로 static void mapDestroy(PyObject* capsule);)으로 선언해야합니다. 파이썬 API는 소멸자를 호출 할 때 함수의 주소를 제대로 찾을 수 있습니다.

... 메모리의 소멸자 주소가 유효한 경우 static 함수를 사용할 필요가 없습니다. 예를 들어 비 캡처 C++ 람다를 함수 포인터로 변환 할 수 있으므로 성공적으로 a C++ non-capturing lambda as a destructor을 사용했습니다. 캡슐 소멸자를 위해 더 잘 작동하는 함수 포인터를 얻어서 전달하는 다른 방법을 원한다면 꼭 이동하십시오.