logo       

missing boost::ref in pyste generated code?: msg#00227

python.c++

Subject: missing boost::ref in pyste generated code?

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


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise