[C++-sig] missing boost::ref in pyste generated code?

Giulio Eulisse giulio.eulisse at cern.ch
Mon May 26 16:40:18 CEST 2003


With the following piece of code:

--CUT-HERE--

#include <iostream>
using std::cout;
using std::endl;

class Ev {
public:
  Ev(int ii) : i(ii) {
    cout <<  "EV " << i << endl;
  }

  virtual ~Ev() {
    cout << "dead Ev " << i << endl;

  }

  int id() const { return i;}


  virtual void me() const=0;

private:
  int i;
};

class REv : public Ev {
public:
  REv(int ii) : Ev(ii){}

  virtual void me() const {
    cout <<  "ReV " << id() << endl;
  }
};

class AA {
public:
  AA() : i(1) {
    cout << "AA " << i << endl;
  }

  virtual ~AA() {
    cout << "dead AA " << i << endl;

  }

  int id() const { return i;}

  virtual void dump() {
    cout << "I'm a AA " << i << endl;
  }

  virtual void here(Ev* ev) const=0;
  virtual void there(Ev const&) const=0;

private:
  int i;
};



class BB : public AA {
public:
  BB(int jj=2) : j(jj) {
    cout << "BB " << j << endl;
  }

  virtual ~BB() {
    cout << "dead BB " << j << endl;

  }

  int jd() const { return j;}

  virtual void dump() {
    cout << "I'm a BB " << j << endl;
  }

  virtual void here(Ev* ev) const {
    cout << "I'm a BB " << j <<" ";
    ev->me();
  }
  virtual void there(Ev const& ev) const {
    cout << "I'm a BB " << j <<" ";
    ev.me();
  }

private:
  int j;
};


inline void hello(AA* a, int k) { REv v(k); a->here(&v);}
inline void hello2(AA* a, int k) { REv v(k); a->there(v);}
---END-CUT---

when pystified with 

---CUT-HERE---
Ev = Class("Ev","Utilities/UtExamples/python/btest.hh")
REv = Class("REv","Utilities/UtExamples/python/btest.hh")
AA = Class("AA","Utilities/UtExamples/python/btest.hh")
BB = Class("BB","Utilities/UtExamples/python/btest.hh")

hello = Function("hello","Utilities/UtExamples/python/btest.hh")
hello2 = Function("hello2","Utilities/UtExamples/python/btest.hh")

---CUT-HERE---

I get the following boostified code:

// Includes
====================================================================
#include <boost/python.hpp>
#include <Utilities/UtExamples/python/btest.hh>
#include <Utilities/UtExamples/python/stest.hh>

// Using
=======================================================================
using namespace boost::python;

// Declarations
================================================================


namespace  {


struct AA_Wrapper: AA
{
    AA_Wrapper(PyObject* self_, const AA & p0):
        AA(p0), self(self_) {}

    AA_Wrapper(PyObject* self_):
        AA(), self(self_) {}

    void dump() {
        call_method< void >(self, "dump");
    }

    void default_dump() {
        AA::dump();
    }

    void here(Ev * p0) const {
        call_method< void >(self, "here", p0); //should be 					      
//boost::ref(*p0)
    }

    void there(const Ev & p0) const {
        call_method< void >(self, "there", p0); //should be
						//boost::ref(p0)
    }

    PyObject* self;
};

struct Ev_Wrapper: Ev
{
    Ev_Wrapper(PyObject* self_, const Ev & p0):
        Ev(p0), self(self_) {}

    Ev_Wrapper(PyObject* self_, int p0):
        Ev(p0), self(self_) {}

    void me() const {
        call_method< void >(self, "me");
    }

    PyObject* self;
};

struct BB_Wrapper: BB
{
    BB_Wrapper(PyObject* self_, const BB & p0):
        BB(p0), self(self_) {}

    BB_Wrapper(PyObject* self_):
        BB(), self(self_) {}

    BB_Wrapper(PyObject* self_, int p0):
        BB(p0), self(self_) {}

    void dump() {
        call_method< void >(self, "dump");
    }

    void default_dump() {
        BB::dump();
    }

    void here(Ev * p0) const {
        call_method< void >(self, "here", p0); //should be 					      
//boost::ref(*p0)
    }

    void default_here(Ev * p0) const {
        BB::here(p0);
    }

    void there(const Ev & p0) const {
        call_method< void >(self, "there", p0);
    }

    void default_there(const Ev & p0) const {
        BB::there(p0);
    }

    PyObject* self;
};

struct REv_Wrapper: REv
{
    REv_Wrapper(PyObject* self_, const REv & p0):
        REv(p0), self(self_) {}

    REv_Wrapper(PyObject* self_, int p0):
        REv(p0), self(self_) {}

    void me() const {
        call_method< void >(self, "me");
    }

    void default_me() const {
        REv::me();
    }

    PyObject* self;
};



}// namespace


// Module
======================================================================
BOOST_PYTHON_MODULE(btest)
{
    class_< AA, boost::noncopyable, AA_Wrapper >("AA", init<  >())
        .def("id", &AA::id)
        .def("dump", &AA::dump, &AA_Wrapper::default_dump)
    ;

    class_< Ev, boost::noncopyable, Ev_Wrapper >("Ev", init< int >())
        .def("id", &Ev::id)
    ;

    class_< BB, bases< AA > , BB_Wrapper >("BB", init< const BB & >())
        .def(init< optional< int > >())
        .def("jd", &BB::jd)
        .def("dump", &BB::dump, &BB_Wrapper::default_dump)
        .def("here", &BB::here, &BB_Wrapper::default_here)
        .def("there", &BB::there, &BB_Wrapper::default_there)
    ;

    class_< REv, bases< Ev > , REv_Wrapper >("REv", init< const REv &
>())
        .def(init< int >())
        .def("me", &REv::me, &REv_Wrapper::default_me)
    ;

    class_< T >("T", init<  >())
        .def(init< const T & >())
    ;

    def("hello", &hello);
    def("hello2", &hello2);
}

---END---

this fails when doing the following in python:

>>> from PyUtExamples import *
>>>
>>> b = BB()
AA 1
BB 2
>>> hello2(b,4)
EV 4
dead Ev 4
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: No to_python (by-value) converter found for C++ type: 2Ev
>>>


as it seem to pass Ev by value, instead of passing it by reference.
We fixed it by adding boost::ref where indicated in the sourcecode as
otherwise it tries to pass things by value. Is this a bug or am I doing
something wrong?

Ciao,
Giulio





More information about the Cplusplus-sig mailing list