[C++-sig] passing a vector of structs

Matthew Scouten matthew.scouten at gmail.com
Wed Oct 17 22:53:31 CEST 2007


On 10/17/07, Matthew Scouten <matthew.scouten at gmail.com> wrote:
> On 10/16/07, Roman Yakovenko <roman.yakovenko at gmail.com> wrote:
> > On 10/16/07, Matthew Scouten <matthew.scouten at gmail.com> wrote:
> > > I have a vector of 'struct foo' in c++ that needs to be passed to a
> > > function python.
> > >
> > > 'struct foo' is an extremely simple structure containing 3 ints and a
> > > trivial ctor.
> > >
> > > so I create a foo_wrapper:
> > >
> > > struct foo_wrapper : foo , wrapper<foo>
> > > {
> > >         foo_wrapper(const foo& f);
> > >         foo_wrapper();
> > > };
> >
> > In this case you don't need to create wrapper
> >
> > > and export it:
> > >
> > > class_<foo_wrapper>("foo")
> > >                 .def(init<>())
> > >                 .def_readwrite("iE", &foo::iE )
> > >                 .def_readwrite("bA", &foo::bA)
> > >                 .def_readwrite("bL", &foo::bL)
> > >                 ;
> > >
> > > next I export a vector of foo_wrappers:
> > >
> > > class_< std::vector<foo_wrapper> >("VectorOfFoo")
> > >                 .def(vector_indexing_suite<
> > std::vector<foo_wrapper>, true >() );
> > >
> > > I pass the vector<foo> to a python function:
> > >
> > > Traceback (most recent call last):
> > >   File "C:\redacted", line 23, in <module>
> > >     pc.RequestExchangeList()
> > > TypeError: No to_python (by-value) converter found for C++ type: class
> > > std::vector<struct foo ,class std::allocator<struct foo > >
> > >
> > > I try to copy the elements to a new vector<foo_wrapper>, it seems to
> > > work fine, untill I try to access an element of that vector and get:
> > >
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in <module>
> > >   File "<stdin>", line 7, in OnExchangeList
> > > TypeError: No to_python (by-value) converter found for C++ type:
> > > struct TTExchangeStruct_wrapper
> > >
> > > So what am I doing wrong? How am I supposed to pass a vector of
> > > structs from c++ to python?
> >
> >
> > You need to post small and complete example.
> >
> >  --
> > Roman Yakovenko
>
> Right, OK:
> TTExchangeStruct_wrapper is my foo_wrapper. I forgot to change that
> when sanitizing and simplifying me example. I split out the problem
> code and made a stand alone compilable example:
>
> c++ & boost::python:
>
> struct foo
> {
>         foo():one(1),two(2),three(3) {}
>
>         int one;
>         int two;
>         int three;
> };
>
> //The std::vector Indexing Suite seems to want this
> //I Don't know why.
> bool operator==(foo lhs ,foo rhs)
> {
>         return &lhs == &rhs;
> }
>
> struct foo_wrapper : foo , wrapper<foo>
> {
>         foo_wrapper(const foo& f);
>         foo_wrapper();
> };
>
> foo_wrapper::foo_wrapper(const foo& exch): foo(exch), wrapper<foo>(){}
>
> foo_wrapper::foo_wrapper(): foo(), wrapper<foo>(){}
>
> class busyBox
> {
> public:
>         int callout();
>         virtual void callback(std::vector<foo> vf) {};
> };
>
> int busyBox::callout()
> {
>         std::vector<foo> vf(10);
>         callback(vf);
>         return 0;
> }
>
> class busyBox_wrapper: public busyBox, public wrapper<busyBox>
> {
> public:
>         busyBox_wrapper();
>         busyBox_wrapper(const busyBox &);
>         int callout();
>         virtual void callback(std::vector<foo> vf);
>         void default_callback(std::vector<foo> vf);
> };
>
> busyBox_wrapper::busyBox_wrapper() : busyBox(), wrapper<busyBox>(){}
>
> busyBox_wrapper::busyBox_wrapper(const busyBox &bb ) : busyBox(bb),
> wrapper<busyBox>(){}
>
> int busyBox_wrapper::callout()
> {
>         return busyBox::callout();
> }
>
> void busyBox_wrapper::callback (std::vector<foo> vf)
> {
>         if (override callbackPy = this->get_override("callback"))
>         {
>
>                 std::vector<foo_wrapper> vfw;
>                 for (unsigned int i = 0; i < vf.size(); ++i)
>                         vfw.push_back(vf[i]);
>
>                 //callbackPy(vf);
>                 callbackPy(vfw);
>
>                 return;
>         }
>         return busyBox::callback(vf);
> }
>
> void busyBox_wrapper::default_callback(std::vector<foo> vf)
> {
>         return busyBox::callback(vf);
> }
>
>
>
> BOOST_PYTHON_MODULE(BusyBox)
> {
>
>         class_<busyBox_wrapper>("busyBox")
>                 .def("callback",&busyBox_wrapper::default_callback)
>                 .def("callout", &busyBox_wrapper::callout);
>
>         class_<foo_wrapper>("foo")
>                 .def(init<>())
>         .def_readwrite("one", &foo::one )
>         .def_readwrite("two", &foo::two)
>         .def_readwrite("three", &foo::three)
>         ;
>
>         class_< std::vector<foo_wrapper> >("std::vectorOfFoo")
>                 .def(vector_indexing_suite< std::vector<foo_wrapper>, true>());
> }
>
> and here is the python code to invoke the error:
>
> import BusyBox
>
> class subBusybox(BusyBox.busyBox):
>         def callback(self, vf):
>                 print [x for x in vf]
>
>
> sbb = subBusybox()
> sbb.callout()
>
> and here it the error itself(it fails while invoking the 'print [x for
> x in vf]' line ):
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 3, in callback
> TypeError: No to_python (by-value) converter found for C++ type:
> struct foo_wrapper
>
>
>
> To reiterate my question: I need to pass a vector of structs from a
> c++ function to a python function. What am I doing wrong?
>

UPDATE: Well, with no reply from the list, I spent all day trying to
find my error. It turns out that I was temporarily stupid.

If the above lines are changed from:

class_< std::vector<foo_wrapper> >("std::vectorOfFoo")
                 .def(vector_indexing_suite< std::vector<foo_wrapper>, true>());

to:

class_< std::vector<foo> >("std::vectorOfFoo")
                 .def(vector_indexing_suite< std::vector<foo>, true>());

it fixes everything.



More information about the Cplusplus-sig mailing list