Hi again,

I've run across another issue confusing me as I try to use pybindgen, in this case it's the treatment of reference parameters in virtual methods where you're allowing the class to be subclassed from python. It looks like the helper class that is generated is making copies of parameters that are being passed as references, which is not what we want. Take the following example C++ classes:

class A {
public:
  A(const int val): mVal(val) {}
private:
  int mVal;
  A();
  A(const A& rhs);
  A& operator=(const A& rhs);
};

class B {
public:
  B() {}
  virtual ~B() {}
virtual void some_virtual_method(const A& a) const { std::cerr << &a << std::endl; }
private:
};

I'd like to be able to create subclasses of B from python, so I try wrapping these classes with the following pybindgen code:

mod = Module("ref_param_example")
mod.add_include('"classes.hh"')
a = mod.add_class("A")
b = mod.add_class("B", allow_subclassing=True)
a.add_constructor([param("int", "val")])
b.add_constructor([])
b.add_method("some_virtual_method", None, [param("A&", "a")], is_const=True, is_virtual=True)

The resulting generated code contains the following:

void
PyB__PythonHelper::some_virtual_method(A & a) const
{
    PyGILState_STATE __py_gil_state;
    B *self_obj_before;
    PyObject *py_retval;
    PyA *py_A;

__py_gil_state = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0); if (!PyObject_HasAttrString(m_pyself, (char *) "_some_virtual_method")) {
        B::some_virtual_method(a);
    if (PyEval_ThreadsInitialized())
        PyGILState_Release(__py_gil_state);
        return;
    }
    self_obj_before = reinterpret_cast< PyB* >(m_pyself)->obj;
reinterpret_cast< PyB* >(m_pyself)->obj = const_cast< B* >((const B*) this);
    py_A = PyObject_New(PyA, &PyA_Type);
    py_A->obj = new A(a);
....

As you can see, the last line quoted here is trying to make a copy of the instance "a" that was passed in. In this example this will not compile because the copy constructor for A is private. In general we don't want to make copies of reference parameters regardless of course.

Am I once again missing something here? Is there some way I can declare that the passed parameters for "some_virtual_method" should really be treated as references and not copied?

Thanks!

Mike.


_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to