0

I have an existing c++ code library that uses a struct with std::vector, which should be exposed to python.

in the header:

struct sFOO
{
    unsigned int start = 3 ;
    double foo = 20.0 ;
};

in the cpp:

namespace myName
{
myfoo::myfoo(){   
    sFOO singlefoo;
    std::vector<sFOO> foos;
}
sFOO singlefoo;            

std::vector<sFOO>* myfoo::get_vector(){
    return &foos;
}
}

and for boost::python snippet:

using namespace boost::python;

class dummy3{};

BOOST_PYTHON_MODULE(vStr)
{
scope myName = class_<dummy3>("myName");

class_<myName::sFOO>("sFOO")
    .add_property("start",&myName::sFOO::start)
    .add_property("foo",&myName::sFOO::foo)
    ;

class_<myName::myfoo>("myfoo", no_init)
    .def(init<>())
    .def("checkfoo",&myName::myfoo::checkfoo)
    .add_property("foos",&myName::myfoo::foos) 
    .add_property("singlefoo",&myName::myfoo::singlefoo)
}

(FYI, fictitious class dummy3 is used to simulate namespace, and using scope is therefore not an option.)

A compilation and importing processes are OK, and I can access singlefoo, but whenever I try to access vector foos, I encounter the error message below.

Python class registered for C++ class std::vector<myName::sFOO, 
std::allocator<myName::sFOO> >

To circumvent this issue, I've firstly tried vector_indexing_suite, but it didn't help exposing pre-defined vector of struct.

I also assumed that there should be a solution related to exposing pointer to python, so I have tried to get a pointer by following:

    .def("get_vector",&myName::myfoo::get_vector) 

which produces compile Error.

Since I am quite a novice to both C++ and Boost, any comments including solution, tips for search, and a suggestion to suitable reference would be greatly appreciated.

Thanks in advance!

1 Answer 1

2

Method .def("get_vector",&myName::myfoo::get_vector) is not working because it returns a pointer to a vector, so it's necessary to inform the policy that defines how object ownership should be managed:

class_<myName::myfoo>("myfoo", no_init)
   // current code
   .def("get_vector", &myfoo::get_vector, return_value_policy<reference_existing_object>())
;

In order to use vector_indexing_suite, it is necessary to implement the equal to operator to the class that it holds:

struct sFOO
{
    unsigned int start = 3 ;
    double foo = 20.0 ;

    bool operator==(const sFOO& rhs)
    {
        return this == &rhs; //< implement your own rules.
    }
};

then you can export the vector:

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

class_<std::vector<sFOO>>("vector_sFOO_")
   .def(vector_indexing_suite<std::vector<sFOO>>())
;
Sign up to request clarification or add additional context in comments.

2 Comments

After minor edits (ex. sFOO -> myName::sFOO), your solution worked like a marvel. Thanks a lot +1
In case, we want to expose third-party structures this approach might not be the best way. I find the method at (boost.org/doc/libs/1_57_0/libs/python/doc/v2/iterator.html) more appropriate.

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.