简体   繁体   中英

Call a C++ function that takes pointer to an array using boost::python

I want to call a C++ function that takes a pointer to an array on a Python list using boost::python. I have a solution like this:

//A function that takes a pointer to an array
void doSomething( int const n, double * a)
{
    for ( std::size_t i=0; i<n; ++i)
        a[i] += 1.;
}  

//My solution 
std::vector<double> add1 (std::vector<double> vec)
{
    doSomething(vec.size(),vec.data());
    return vec;
}

//boost::python registration 
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(vector2)
{
    using namespace boost::python;
    def("doSomething", doSomething);
    def("add1", &add1);

    class_<std::vector<double> >("VectorOfDouble")
        .def(vector_indexing_suite<std::vector<double> >());
}

Which works in Python:

>>> import vector2
>>> lint=[1,2,3,4]
>>> old_vector = vector2.VectorOfDouble()
>>> old_vector.extend(arg for arg in lint)
>>> new_vector=vector2.add1(old_vector)
>>> print list(old_vector)
[1.0, 2.0, 3.0, 4.0]
>>> print list(new_vector)
[2.0, 3.0, 4.0, 5.0]

However, this requires copying the original list into a new list. As the arrays I am working with are very large, I'd prefer avoiding this. A modification of my solution like this doesn't return any errors, but the original object is not modified:

//My solution 
void add1 (std::vector<double> vec)
{
    doSomething(vec.size(),vec.data());
}

In python :

>>> import vector2
>>> lint=[1,2,3,4]
>>> old_vector = vector2.VectorOfDouble()
>>> old_vector.extend(arg for arg in lint)
>>> print list(old_vector)
[1.0, 2.0, 3.0, 4.0]
>>> vector2.add1(old_vector) 
>>> print list(old_vector)
[1.0, 2.0, 3.0, 4.0]

Is there a way to call doSomething and modify the original vector without creating a new one?

By the way, following a suggestion from another post, I also tried to write a simple wrapper to get a pointer to the first element of the vector:

std::string * pointer (std::string& p)
{
    return &p;
}

But it seems that the Boost registration of any function that returns a pointer produces a very lengthy error at compile time.

Note you are taking in std::vector as a copy.

Have you tried taking it in as a reference and seen what the result would be?

// take by reference
void add1 (std::vector<double>& vec)
{
    doSomething(vec.size(),vec.data());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM