问题
I'm trying to get Boost Python to play nicely with std::shared_ptr. Currently, I'm receiving this error:
Traceback (most recent call last):
File "test.py", line 13, in <module>
comp.place_annotation(circle.centre())
TypeError: No to_python (by-value) converter found for C++ type: std::shared_ptr<cgl::Anchor>
From calling circle.centre(), which returns an std::shared_ptr. I could change every std::shared_ptr to a boost::shared_ptr (which Boost Python plays nicely with) however the amount of code to change in pretty considerable and I'd like to use the standard library.
The circle method is declared like this:
const std::shared_ptr<Anchor> centre() const
{
return Centre;
}
The anchor class like this:
class Anchor
{
Point Where;
Annotation* Parent;
public:
Anchor(Annotation* parent) :
Parent(parent)
{
// Do nothing.
}
void update(const Renderer& renderer)
{
if(Parent)
{
Parent->update(renderer);
}
}
void set(Point point)
{
Where = point;
}
Point where() const
{
return Where;
}
};
And the relevant Boost Python code is:
class_<Circle, bases<Annotation> >("Circle", init<float>())
.def("radius", &Circle::radius)
.def("set_radius", &Circle::set_radius)
.def("diameter", &Circle::diameter)
.def("top_left", &Circle::top_left)
.def("centre", &Circle::centre);
// The anchor base class.
class_<Anchor, boost::noncopyable>("Anchor", no_init)
.def("where", &Anchor::where);
I'm using Boost 1.48.0. Any ideas?
回答1:
Looks like boost::python doesn't support C++ 11 std::shared_ptr.
If you have a look to file boost/python/converter/shared_ptr_to_python.hpp you'll find implementation of template function shared_ptr_to_python(shared_ptr<T> const& x) for boost::shared_ptr (it explain why the code works fine for boost::shared_ptr).
I think you have several options:
- use boost::shared_ptr (which you trying to avoid)
- write your implementation of shared_ptr_to_python for std::shared_ptr (IMHO the best option)
- send request to boost::python developers to support std::shared_ptr
回答2:
Unless I've misunderstood, I think this solves your problem:
boost::python::register_ptr_to_python<std::shared_ptr<Anchor>>();
http://www.boost.org/doc/libs/1_57_0/libs/python/doc/v2/register_ptr_to_python.html
回答3:
There's a bug report for this: https://svn.boost.org/trac/boost/ticket/6545
Looks like someone is working on it.
回答4:
A snippet from http://boost.2283326.n4.nabble.com/No-automatic-upcasting-with-std-shared-ptr-in-function-calls-td4573165.html:
/* make boost::python understand std::shared_ptr */
namespace boost {
template<typename T>
T *get_pointer(std::shared_ptr<T> p)
{
return p.get();
}
}
Worked for me. You would define your classes like:
class_<foo, std::shared_ptr<foo>>("Foo", ...);
With this, other methods returning std::shared_ptr<foo>
will Just Work.
Some magic may be required for virtual functions/polymorphism, that should be covered in the thread I linked to.
来源:https://stackoverflow.com/questions/13986581/using-boost-python-stdshared-ptr