Well, I've been checking this for a while, couldn't find an answer to it.
I wanted to append an object which is exposed to python, say Foo:
struct Foo {
Foo(){ std::cout << "Creating a Foo object" << std::endl;}
virtual ~Foo(){ std::cout << "Destroying a Foo object" << std::endl;}
};
I work with the Foo inherited objects, and at some point I want to append them to a python list. For this, I created a FooWrapper, which inherits from Foo and use the copy constructor to
struct FooWrapper : public Foo {
FooWrapper(const Foo& foo):Foo(foo){ std::cout << "Creating a copy from foo using FooWrapper" << std::endl;}
virtual ~FooWrapper(){ std::cout << "Destroying a FooWrapper object" << std::endl;}
};
This is exposed to python:
BOOST_PYTHON_MODULE(foo_module)
{
using namespace py = boost::python;
py::class_<FooWrapper>("FooWrapper", py::no_init)…
}
I have a method which appends the final Foo objects as FooWrapper to a python list, say:
void appendFoosToList(py::list &list)
{
for ( const Foo* foo : m_foos )
{
list.append( FooWrapper( *foo ) );
}
}
How could I make so that instead of creating a temporary object and then copying to the list, that I append to the list this object, without having to copy the temporary?
I've read many documentations (boost_faq, boost_python_wiki), many times I got this runtime error:
TypeError: No to_python (by-value) converter found for C++ type:
BPL was unable to get C++ value from Python object.
For example, when calling extract(.attr("len")()) to get object length you omitted "()".
And didn't manage to find a solution.
I couldn't find a clear documentation about this, so I come here as the final resort.
boost::shared_ptr, that makes it possible to transparently move objects between c++ and python without worrying about ownership and lifetime (just careful with circular pointer structures). It might not work everywhere, but is useful for some cases.