Using Boost Python & std::shared_ptr

扶醉桌前 提交于 2019-12-04 16:26:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!