gpt4 book ai didi

python - numpy 数组 C api

转载 作者:太空狗 更新时间:2023-10-29 20:52:57 26 4
gpt4 key购买 nike

我有一个返回 std::vector 的 C++ 函数,我想在 python 中使用它,所以我使用的是 C numpy api:

static PyObject *
py_integrate(PyObject *self, PyObject *args){
...
std::vector<double> integral;
cpp_function(integral); // This changes integral
npy_intp size = {integral.size()};
PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &(integral[0]));
return out;
}

这是我在 python 中调用它的方式:

import matplotlib.pyplot as plt

a = py_integrate(parameters)
print a
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(a)
print a

发生的事情是:第一次打印没问题,值是正确的。但是当我绘制 a 时,它们不是;在第二个打印中,我看到非常奇怪的值,如 1E-308 1E-308 ...0 0 0 ... 作为未初始化的内存。我不明白为什么第一次打印没问题。

部分解决方案(无效):

static void DeleteVector(void *ptr)
{
std::cout << "Delete" << std::endl;
vector * v = static_cast<std::vector<double> * >(ptr);
delete v;
return;
}

static PyObject *
cppfunction(PyObject *self, PyObject *args)
{
std::vector<double> *vector = new std::vector<double>();
vector->push_back(1.);
PyObject *py_integral = PyCObject_FromVoidPtr(vector, DeleteVector);
npy_intp size = {vector->size()};
PyArrayObject *out;
((PyArrayObject*) out)->base = py_integral;
return (PyObject*)(out);
}

最佳答案

您的 std::vector 对象似乎是该函数的本地对象。 PyArray_SimpleNewFromData 不会复制您传递给它的数据。它只是保留一个指针。因此,一旦您的 py_integrate 函数返回, vector 就会被释放。打印第一次工作是因为还没有任何内容覆盖释放的内存,但是当您进行下一次打印时,其他东西已经使用了该内存,导致值不同。

您需要创建一个拥有自己存储空间的NumPy数组,然后将数据复制到其中。

或者,在堆上分配你的 vector 。然后将指向它的指针存储在 CObject 中.提供删除 vector 的析构函数。然后,看看C级PyArrayObject类型。它有一个名为 basePyObject * 成员。将您的 CObject 存储在那里。然后,当 NumPy 数组被垃圾回收时,此基础对象的引用计数将减少,并且假设您没有在其他地方获取它的副本,由于您提供的析构函数,您的 vector 将被删除。

固定器上层

您忘记实际创建 PyArray。试试这个:

(您没有发布DeleteVector,所以我只能希望它是正确的)

std::vector<double> *vector = new std::vector<double>();
vector->push_back(1.);
PyObject *py_integral = PyCObject_FromVoidPtr(vector, DeleteVector);
npy_intp size = {vector->size()};
PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &((*vector)[0]));
((PyArrayObject*) out)->base = py_integral;
return out;

注意:我不是 C++ 程序员,所以我只能假设 &((*vector)[0]) 使用指向 vector 的指针按预期工作。我知道如果你增长它, vector 会重新分配它的存储区域,所以在获得该指针后不要增加它的大小,否则它将不再有效。

关于python - numpy 数组 C api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2924827/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com