I have one remaining problem that I know of with this code. How do I make it possible to compare the wrapped ref_ptrs for equality? I am assuming that I need to add an __eq__ operator for the ref_ptr types but since they are used as held_type I am not really exposing them in the "normal" way.
Yup -- you'll have to implement __eq__.
<osg._osg.Group object at 0xb785fcac>
n.getCore() <osg._osg.Group object at 0xb785f16c> g == n.getCore() False
Does anyone know if this is also an issue when wrapping an API and using boost::shared_ptr<> as the held type? If so, how is that case handled?
It works sometimes, and not others. As you discovered, boost python will store the python object in a custom shared_ptr deleter. Converting to-python, I believe it will see if the shared_ptr has its custom deleter and will use the python object in there if it is. The problem is that if you're using your own shared_ptrs, then you may pass a shared_ptr to boost python which doesn't have the special custom deleter, and you'll end up with multiple python objects representing the same c++ object. What you really want is to have just a single python object associated with each C++ instance. I call this problem "object identity", and it's been discussed on this list before. It is *possible* to solve this problem with boost python as is, but it requires doing *very* nasty things using internal api. I think the real solution is to extend boost python so that: - You can tell boost python that your c++ object can manage its python identity. - As soon as boost python produces a python object for your c++ object, it calls you to establish the identity. - Whenever (a pointer to) that c++ instance is to be converted to-python, boost python will consult you to find the python object. Incidentally, wrapper<T> already does this stuff mostly right. I hope to make a patch to support this someday, but it probably won't be that soon. Anyway, in the meantime, if you just implement __eq__ in the obvious way, it should work. Alex