加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

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

发布时间:2020-12-16 22:16:19 所属栏目:Python 来源:网络整理
导读:我想在C/C++中为numpy数组分配数字,并将它们作为numpy数组传递给python.我可以用PyArray_SimpleNewFromData做. 问题是我还想注册一个当numpy数组引用计数器达到零时应该从Python调用的函数,这将调用C端的一些析构函数语义这是我需要的一个伪示例: float* ar

我想在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数组的基础.这听起来很棘手,但可以通过python中的capsules轻松实现.让我举个例子,

假设您有以下代码,

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

现在增加你的代码,(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窃取引用.

希望这可以帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读