2

I want to return array from c++ and receive it in python code as a numpy array. I used PyArray_SimpleNewFromData and Py_BuildValue but my program is just quit without any error/warning message where 'PyArray_SimpleNewFromData' should run, so it's bit hard to understand what is the problem.

Here is a part of my code where I return the array.

#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.
}

Please let me know if you have any ideas, or need further information.

1 Answer 1

3

Read the docs (emphasis mine):

PyObject* PyArray_SimpleNewFromData(int nd, npy_intp const* dims, int typenum, void* data)

Create an array wrapper around data pointed to by the given pointer. The array flags will have a default that the data area is well-behaved and C-style contiguous. The shape of the array is given by the dims c-array of length nd. The data-type of the array is indicated by typenum. If data comes from another reference-counted Python object, the reference count on this object should be increased after the pointer is passed in, and the base member of the returned ndarray should point to the Python object that owns the data. This will ensure that the provided memory is not freed while the returned array is in existence. To free memory as soon as the ndarray is deallocated, set the OWNDATA flag on the returned ndarray.

The first argument nd (length_arr in your case) is the number of dimensions, so the function will know the number of entries of the second argument dims (most C functions expect to to told the length of arrays passed into them, unless they are terminated somehow, e.g. null terminated character arrays/strings). Think of dims being arr.shape, and nd being len(arr.shape) (number of dimensions).

In your case, dims[0] should be 512 * 512 and length_arr should be 1. You have it the other way round.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much for your reply! I made a stupid mistake! I modified it, but still PyArray_SimpleNewFromData doesn't work...Probably there is another stupid mistake somewhere. I'm working on it now. Thank you again. :)
A debugger, or copious amounts of debugging output, will surely light your way to the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.