Python 如何为C分配的numpy数组注册析构函数?
我想在C/C++中为numpy数组分配数字,并将它们作为numpy数组传递给python。我可以用它 问题是,我还想注册一个函数,当numpy数组引用计数器达到零时,应该从Python调用该函数,这将在C端调用一些析构函数语义。。。以下是我需要的一个伪示例:Python 如何为C分配的numpy数组注册析构函数?,python,c,numpy,Python,C,Numpy,我想在C/C++中为numpy数组分配数字,并将它们作为numpy数组传递给python。我可以用它 问题是,我还想注册一个函数,当numpy数组引用计数器达到零时,应该从Python调用该函数,这将在C端调用一些析构函数语义。。。以下是我需要的一个伪示例: float* arr; PyObject* np_arr; void (*destructor)(float* arr); // ... C-allocate array on arr, ... // ... // ... init
float* arr; PyObject* np_arr; void (*destructor)(float* arr);
// ... C-allocate array on arr, ...
// ...
// ... initialize destructor with some suitable value, and then:
np_arr = /* ... create the array to wrap arr,
and to use destructor on some meaningful way ... */
有一种简单的方法吗?这个想法是创建一个Python对象,它知道如何在内存被破坏时释放内存,并将其作为返回的C分配numpy数组的基础。这听起来很棘手,但可以通过python中的一些东西轻松实现。我举个例子, 假设您有以下代码
PyObject *arr;
int nd = 2;
npy_intp dims[] = {5, 10};
double *data = some_function_that_returns_a_double_star(x, y, z);
arr = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, (void *)data);
return arr;
这里有一个明显的内存泄漏,因为在删除arr之前,您无法释放数据,如红色警告框中所示。另一方面,解决这个问题很容易。定义一个基本上是析构函数的函数,它知道如何进行垃圾收集
void capsule_cleanup(PyObject *capsule) {
void *memory = PyCapsule_GetPointer(capsule, NULL);
// Use your specific gc implementation in place of free if you have to
free(memory);
}
现在将代码扩充为
PyObject *arr;
int nd = 2;
npy_intp dims[] = {5, 10};
double *data = some_function_that_returns_a_double_star(x, y, z);
arr = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, (void *)data);
PyObject *capsule = PyCapsule_New(data, NULL, capsule_cleanup);
// NULL can be a string but use the same string while calling PyCapsule_GetPointer inside capsule_cleanup
PyArray_SetBaseObject((PyArrayObject *) arr, capsule);
return arr;
无需Py_DECREF
胶囊。函数PyArray\u SetBaseObject
窃取引用
希望这有帮助 这不是一个简单的方法,但是我认为这个URL会回答你的问题