Rug*_*rra 8 c python numpy vector python-c-api
我有一个C++函数返回一个std :: vector,我想在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;
}
Run Code Online (Sandbox Code Playgroud)
这是我从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
Run Code Online (Sandbox Code Playgroud)
会发生什么:第一次打印没问题,值是正确的.但是当我描绘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);
}
Run Code Online (Sandbox Code Playgroud)
kwa*_*ord 11
您的std::vector对象似乎是该功能的本地对象.PyArray_SimpleNewFromData不会复制您传递的数据.它只是一个指针.因此,一旦你的py_integrate函数返回,向量就会被释放.打印工作是第一次,因为还没有任何内容写入释放的内存,但是当你进入下一个打印时,其他东西已经使用了那个内存,导致值不同.
您需要创建一个拥有自己的存储空间的NumPy数组,然后将数据复制到其中.
或者,在堆上分配矢量.然后在CObject中存储指向它的指针.提供删除向量的析构函数.然后,看一下C级PyArrayObject类型.它有一个PyObject *叫做的成员base.存放在CObject那里.然后当NumPy数组被垃圾收集时,该基础对象的引用计数将递减,并且假设您没有在其他地方获取它的副本,由于您提供的析构函数,您的向量将被删除.
你忘了实际创建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;
Run Code Online (Sandbox Code Playgroud)
注意:我不是C++程序员,所以我只能假设它&((*vector)[0])与指向向量的指针一样工作.我知道如果你增长它,矢量会重新分配它的存储区域,所以在获得指针之后不要增加它的大小,否则它将不再有效.
| 归档时间: |
|
| 查看次数: |
5676 次 |
| 最近记录: |