[C++-sig] Is there a way to automatically convert a smart_ptr to a held_type (try 2)

Allen Bierbaum abierbaum at gmail.com
Wed Sep 6 01:09:12 CEST 2006


On 8/30/06, Alex Mohr <amohr at pixar.com> wrote:
> > What I need is a way to tell boost python that anytime it needs to
> > convert a ptr<Base> to python it should first convert it to a
> > ref_ptr<Base>  (using a standard copy constructor in ref_ptr<>) and
> > then use this ref_ptr as the held type like normal.
> >
> > At first I thought that implicitly_convertible<> would help:
> >
> > implicitly_convertible<ptr<Base>, ref_ptr<Base> >();
> >
> > But this doesn't seem to do anything for me. (this really isn't too
> > surprising since this isn't what implicitly_convertible is for, but it
> > seemed worth a try).
> >
> > Has anyone else ran into anything similar?  Any ideas?
>
> At first glance, it seems like you want to register a to-python
> conversion for all your ptr<T> types.  Note that all code I write in
> this message is untested:
>
> template <class T>
> struct ptr_to_python {
>      static PyObject *convert(ptr<T> const &p) {
>          return Py_INCREF(object(ref_ptr<T>(p)).ptr());
>      }
> };
>
> Then you need to do this for each class you register:
>
> to_python_converter<ptr<T>, ptr_to_python<T> >();
>

Thanks Alex, this worked great.  I had to change the Py_INCREF to a
bp::incref but otherwise things are all good.

But now I have a rather strange followup question.

It seems that Boost.Python is doing some magic behind the scenes to
convert an object coming from C++ as a smart pointer whose wrapped
pointer is NULL into a Python "None".  The is great, and was a
wonderful surprise.  But now I need to find a way to make it happen in
the other direction.

How does boost.python convert a parameter of "None" into an
object/smart_ptr to pass to C++?

I need to find a way to call a C++ method like:

void setObject(ptr<Base> obj);

from Python and call it in Python as "setObject(None)" and instruct
boost.python to convert this into a call behind the scenes in C++ to:

setObject(NullPtr);

where "NullPtr" is a global const value defined by the library that is
used to signify a NULL shared pointer throughout the system.  (the
reason it needs something like this is a little complex, but it is not
my library so I can't change this part much.)

Alternatively, I could probably make it work if I could get
boost.python to make a call like:

setObject(ref_ptr<Base>(NULL) )

as I think I could get the library to automatically convert
ref_ptr<Base>(NULL) into a NullPtr.

Any ideas?


-Allen



More information about the Cplusplus-sig mailing list