Pass C++ variable as reference to Python using Boost

Viewed 171

I am trying to pass an argument by reference to a Python function from C++ using the Boost Python library (as well as the Boost Numpy extension). The object in question is an ndarray, and passing it by value works just fine as demonstrated below:

#include <boost/python/numpy.hpp>
#include <cstdlib>
#include <iostream>
#include <array>

namespace p = boost::python;
namespace np = boost::python::numpy;


int main(int argc, char* argv[]) {
    // Set PYTHONPATH 
    setenv("PYTHONPATH", ".", 1);

    // Initialize Python 
    Py_Initialize();

    // Initialize Numpy 
    np::initialize();

    // Create array of 5 integers
    std::array<int,5> arr = { 2,4,6,8,10};

    // Create Numpy array of ints.
    p::tuple shape = p::make_tuple(5);
    np::dtype dtype = np::dtype::get_builtin<int>();
    np::ndarray np_arr = np::from_data(arr.data(),
        dtype,
        shape,
        p::make_tuple(sizeof(int)),
        p::object());

    try {
        // Import Python module.
        p::object python_module = 
        p::import("pytest");

        // Pull class from module.
        p::object start_class = python_module.attr("Foo")();

        // Call class function with argument
        start_class.attr("bar")(np_arr);

        // Call function again
        start_class.attr("bar")(np_arr);
    }
    catch (const boost::python::error_already_set&) {
        // Print Python Errors
        PyErr_Print();
    }

    return 0;
}

The relevant pytest.py file is as follows:

class Foo:
    def bar(self, x):
        print(x)
        x = 2*x

This prints out [ 2 4 6 8 10] [ 2 4 6 8 10] as expected. However, I would like for the ndarray to be passed by reference in order to avoid any expensive copies (i.e. the output would be [ 2 4 6 8 10] [ 4 8 12 16 20]).

According to the documentation, the way to do this seems to be through boost::ref. However, when I wrap the argument as a reference (by changing the function call to start_class.attr("bar")(boost::ref(np_arr));) I get the following error message from Python: TypeError: No Python class registered for C++ class boost::python::numpy::ndarray

0 Answers
Related