python - 如何为 C 分配的 numpy 数组注册析构函数?

标签 python c numpy

我想在 C/C++ 中为一个 numpy 数组分配数字,并将它们作为一个 numpy 数组传递给 python。我可以用 PyArray_SimpleNewFromData 来做.

问题是我还想注册一个函数,当 numpy 数组引用计数器达到零时应该从 Python 调用该函数,并且会在 C 端调用一些析构函数语义......这是一个伪示例我需要什么:

 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 数组的基础。这听起来很棘手,但可以通过称为 capsules 的东西轻松实现。在 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 被删除,正如它所说的 here在红色警告框中。另一方面,解决这个问题很容易。定义一个函数,它基本上是一个知道如何进行垃圾收集的析构函数。

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_SetBaseObject 窃取引用。

希望这对您有所帮助!

关于python - 如何为 C 分配的 numpy 数组注册析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6811749/

相关文章:

c - 用C语言设计 "web app"后端的方法?

python - 如何读取大型文本文件避免逐行读取::Python

python - 如何处理 request.head(url) 中的超时错误?

python - 在 python/numpy 中切片时“环绕”

python - 合并两列以消除重复的行

python - 如何在 FUSE readdir 调用中返回文件统计信息?

c - 在c中用信号量同步两个子进程

c - OS X Yosemite 上的堆栈崩溃?

python - 如何在Python中填充矩阵以使其大小均匀

python - 具有三个输出的 Matlab polyval 函数在 Python/Numpy 中等效