On 9/7/06, Alex Mohr <amohr@pixar.com> wrote:
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.
The non-obvious part of this for me is: - Does this mean that I now need to explicitly wrap (expose using bp::class_ ) all the ref_ptr<> types? I haven't had to do that thus far because it was handled internally somehow because I used it has the held_type for all my classes. If I expose them manually do I run the risk of breaking any of the held_type functionality? -Allen