[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