18

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?

3
  • try class_<Anchor, shared_ptr<Anchor>>("Anchor", no_init) Commented Dec 22, 2012 at 20:25
  • @kassak I've tried that, same problem. Commented Dec 26, 2012 at 2:45
  • The swig documentation has some explanation on wrapping smart pointers that might be of help Commented Dec 29, 2012 at 18:43

4 Answers 4

17
+50

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
Sign up to request clarification or add additional context in comments.

2 Comments

github.com/boostorg/python/issues/29 There is an open ticket related to supporting std::shard_ptr.
how can we delete the above declaration of the shared_ptr. Suppose, i have shared_ptr<Net<float> > net; i want to empty the data in net at end of program. Any help regarding this will be helpful. Thank you
6

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

Comments

1

There's a bug report for this: https://svn.boost.org/trac/boost/ticket/6545

Looks like someone is working on it.

1 Comment

I don't think it is being worked on; the guy asks for someone to take over.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.