2

boost::python を使用して、Python リストの配列へのポインターを受け取る C++ 関数を呼び出したいと考えています。私はこのような解決策を持っています:

//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> >());
}

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]

ただし、これには元のリストを新しいリストにコピーする必要があります。私が扱っている配列は非常に大きいので、これは避けたいと思います。このような私のソリューションの変更はエラーを返しませんが、元のオブジェクトは変更されません:

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

パイソンで:

>>> 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]

doSomething を呼び出して、新しいベクターを作成せずに元のベクターを変更する方法はありますか?

ちなみに、別の投稿からの提案に従って、ベクトルの最初の要素へのポインターを取得するための単純なラッパーも作成しようとしました。

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

しかし、ポインターを返す関数をBoost登録すると、コンパイル時に非常に長いエラーが発生するようです。

4

1 に答える 1