[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