2009/6/25 Gustavo Carneiro <gjcarne...@gmail.com> > > > 2009/6/25 J. Michael Owen <mikeo...@llnl.gov> > >> I can see what you're worried about here, but as a practical matter it is >> very useful to be able to pass stuff by reference, and copying it under the >> hood will break code. For instance, if the virtual functions modify the >> state of the parameters passed by reference it will just not function >> correctly when a copy is made. Or in the example I sent when copy >> constructors are not available it won't even compile! >> >> In Boost.Python this can be handled by wrapping the intermediate arguments >> with the boost::ref() function, which tells Boost.Python to pass the thing >> along as reference rather than making a copy and on my own head be it if I >> do something nefarious with that reference. I guess what I would like in >> this case is the equivalent of an "on my own head be it" option. This is >> kind of how I think of the pointer passing policy, like with the >> "caller_owns_return" option. Wouldn't it be reasonable to allow us to >> specify optionally that references should not be copied, but rather passed >> along natively? With the default policy still being the more memory safe >> option of doing the copy? > > > I can't really fault your logic. > > I just thought of something that makes some sense. If the wrapper did > something like: > > _wrap_my_virtual_method (A &a) > { > PyA *py_A; > > py_A = PyObject_New(PyA, &PyA_Type); > py_A->obj = &a; > > // --- code to call into Python (without consuming a reference to py_A) > --- > > py_A->obj = NULL; > Py_DECREF(py_A); > } > > At the end of the virtual method call, if the called python code decided to > keep a reference to py_A, it will have a py_A with NULL C++ object and so > any method call on it will crash. >
After starting to look at this issue, I realized that this solution is already implemented actually, but I had forgotten! :P You need to tell pybindgen that the reference parameter is INOUT, thus: ReferenceManipulator.add_method('do_manipulate_object', 'void', [Parameter.new('ManipulatedObject&', 'obj', direction=Parameter.DIRECTION_INOUT)], is_virtual=True, is_pure_virtual=True) Then everything works as expected. I am closing the bug by merely adding a unit test to cover this problem. Should work in pybindgen 0.10 as well. Take care, -- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig