[C++-sig] passing a vector of structs
Matthew Scouten
matthew.scouten at gmail.com
Wed Oct 17 16:31:26 CEST 2007
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?
More information about the Cplusplus-sig
mailing list