问题描述
我想从 C++ 返回数组并在 python 代码中作为 numpy 数组接收它。 我使用了 PyArray_SimpleNewFromData 和 Py_BuildValue,但我的程序只是退出,没有任何错误/警告消息,“PyArray_SimpleNewFromData”应该运行,所以很难理解是什么问题。
这是我返回数组的代码的一部分。
#include <Python.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "numpy\ndarraytypes.h"
#include "numpy\ndarrayobject.h"
#include "numpy\arrayobject.h"
static PyObject* cfunc(PyObject* self,PyObject* args)
{
PyArrayObject* arr;
double* carr;
if (!PyArg_ParseTuple(args,"O",&arr))
{
return NULL;
}
carr = (double*)PyArray_DATA(arr);
...// do some job here to change the values of carr elements.
npy_intp dims[1];
dims[0] = 1; // Will be a 1D numpy array
int length_arr = 512 * 512;
PyObject* arr_return = PyArray_SimpleNewFromData(length_arr,dims,NPY_DOUBLE,(void*)carr);
return Py_BuildValue("O",arr_return); // Python code will receive the array as numpy array.
}
如果您有任何想法或需要更多信息,请告诉我。
解决方法
Read the docs(强调我的):
PyObject* PyArray_SimpleNewFromData(int nd,npy_intp const* dims,int typenum,void* data)
围绕给定指针指向的数据创建一个数组包装器。数组标志将有一个默认值,即数据区是行为良好且 C 风格连续的。 数组的形状由长度为 nd 的 dims c-array 给出。 数组的数据类型由 typenum 表示。如果数据来自另一个引用计数的 Python 对象,则在传入指针后应增加该对象上的引用计数,并且返回的 ndarray 的基成员应指向拥有该数据的 Python 对象。这将确保在返回的数组存在时不会释放提供的内存。要在 ndarray 释放后立即释放内存,请在返回的 ndarray 上设置 OWNDATA 标志。
第一个参数 nd
(在您的情况下为 length_arr
)是维数,因此该函数将知道第二个参数 dims
的条目数(大多数 C 函数期望告诉传递给它们的数组的长度,除非它们以某种方式终止,例如空终止字符数组/字符串)。想象一下 dims
是 arr.shape
,而 nd
是 len(arr.shape)
(维度数)。
在您的情况下,dims[0]
应为 512 * 512
,而 length_arr
应为 1
。反之亦然。