[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