2016-09-03 22 views
5

Theo documentation, đối số thứ ba để PyCapsule_New() có thể chỉ định một destructor, mà tôi giả định nên được gọi khi viên nang bị phá hủy.Phá hủy một đối tượng 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); 

} 

Tuy nhiên, khi tôi nhanh chóng các đối tượng và xóa nó hay thoát khỏi Python console, destructor dường như không thể được gọi là:

>>> 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 $ 

tôi đoán là nó có một cái gì đó để làm với các Py_BuildValue() trả lại một tham chiếu mới để "viên nang", mà khi xóa không ảnh hưởng đến bản gốc. Dù sao, làm thế nào tôi sẽ đi về việc đảm bảo rằng các đối tượng bị phá hủy đúng cách?

Sử dụng Python 3.4.3 [GCC 4.8.4] (trên linux)

Trả lời

0

Py_BuildValue("O", thingy) sẽ chỉ tăng các refcount cho thingy và gửi lại - các tài liệu nói rằng nó trả về một “tham chiếu mới”, nhưng đó không phải là khá đúng khi bạn vượt qua nó PyObject* hiện có.

Nếu các chức năng này của bạn - tất cả được xác định trong cùng một đơn vị dịch, hàm hủy có thể phải được khai báo static (vì vậy chữ ký đầy đủ của nó sẽ là static void mapDestroy(PyObject* capsule);) để đảm bảo API Python có thể tra cứu địa chỉ của các hàm đúng khi đến lúc gọi hàm hủy.

… Bạn không phải sử dụng chức năng static, miễn là địa chỉ của hàm hủy trong bộ nhớ hợp lệ. Ví dụ: tôi đã sử dụng thành công a C++ non-capturing lambda as a destructor, vì lambdas C++ không bắt được có thể được chuyển đổi thành con trỏ hàm; nếu bạn muốn sử dụng một cách khác để có được và đưa ra một con trỏ hàm cho destructor viên nang của bạn mà làm việc tốt hơn cho bạn, bằng mọi cách đi cho nó.

Các vấn đề liên quan