1

Following examples and the numpy C-API (http://docs.scipy.org/doc/numpy/reference/c-api.html), I'm trying to access numpy array data in cpp, like this:

#include <Python.h>
#include <frameobject.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION // TOGGLE OR NOT
#include "numpy/ndarraytypes.h"
#include "numpy/arrayobject.h"
...
// here I have passed "some_python_object" to the C code
// .. and "some_python_object" has member "infobuf" that is a numpy array
//
unsigned long* fInfoBuffer;
PyObject* infobuffer = PyObject_GetAttrString(some_python_object, "infobuf");
PyObject* x_array    = PyArray_FROM_OT(infobuffer, NPY_UINT32);
fInfoBuffer          = (unsigned long*)PyArray_DATA(x_array); // DOES NOT WORK WHEN API DEPRECATION IS TOGGLED

When the API deprecation is toggled, I get, when compiling:

error: cannot convert ‘PyObject* {aka _object*}’ to ‘PyArrayObject* {aka tagPyArrayObject*}’ for argument ‘1’ to ‘void* PyArray_DATA(PyArrayObject*)’

What would be the legitimate way of doing this in numpy 1.7+ ?

2 Answers 2

3

You could try using a higher-level library that wraps numpy arrays in C++ containers with proper container semantics.

Try out xtensor and the xtensor-python bindings.

There is also a cookiecutter to generate a minimal C++ extension project with all the boilerplate for testing, html documentation and setup.p...

Example: C++ code

#include <numeric>                        // Standard library import for std::accumulate
#include "pybind11/pybind11.h"            // Pybind11 import to define Python bindings
#include "xtensor/xmath.hpp"              // xtensor import for the C++ universal functions
#define FORCE_IMPORT_ARRAY                // numpy C api loading
#include "xtensor-python/pyarray.hpp"     // Numpy bindings

double sum_of_sines(xt::pyarray<double> &m)
{
    auto sines = xt::sin(m);
    // sines does not actually hold any value, which are only computed upon access
    return std::accumulate(sines.begin(), sines.end(), 0.0);
}

PYBIND11_PLUGIN(xtensor_python_test)
{
    xt::import_numpy();
    pybind11::module m("xtensor_python_test", "Test module for xtensor python bindings");

    m.def("sum_of_sines", sum_of_sines,
        "Computes the sum of the sines of the values of the input array");

    return m.ptr();
}

Python Code:

import numpy as np
import xtensor_python_test as xt

a = np.arange(15).reshape(3, 5)
s = xt.sum_of_sines(v)
s
Sign up to request clarification or add additional context in comments.

2 Comments

Question refered to the C-API, the answer related to C++ code. The question remains, how would one do this using the C-API.
The C++ code in question makes use of the C API, and wraps it in higher level constructs. Also, the original question says "I'm trying to access numpy array data in cpp,"
0

It is because PyArray_DATA expects a PyArrayObject*. You can try to change the type of x_array:

PyArrayObject* x_array = (PyArrayObject*) PyArray_FROM_OT(infobuffer, NPY_UINT32)

Comments

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.