将数组从 C++ 返回到 python

问题描述

我想从 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 函数期望告诉传递给它们的数组的长度,除非它们以某种方式终止,例如空终止字符数组/字符串)。想象一下 dimsarr.shape,而 ndlen(arr.shape)(维度数)。

在您的情况下,dims[0] 应为 512 * 512,而 length_arr 应为 1。反之亦然。