On 8/30/06, Alex Mohr <amohr@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