[C++-sig] problem chaning object state using a python class that inherits from c++ class
Alexis H. Rivera-Rios
ahrivera at yahoo.com
Wed Aug 17 00:47:49 CEST 2005
David,
Here's a simpler version:
struct Data
{
int a;
};
class B
{
public:
virtual void Update(Data& a) = 0;
~B() {}
};
class D : public B
{
virtual void Update(Data& a)
{
a.a = 10;
}
};
class C
{
public:
void SetBptr(B* newB)
{
Bptr = newB;
}
void Update()
{
// this doesn't seem to work correctly if Bptr is a
python object
Bptr->Update(d);
}
int GetData_a() const
{
return d.a;
}
private:
Data d;
B* Bptr;
};
here is the generated code from pyste:
// Boost Includes
==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>
// Includes
====================================================================
#include "test.h"
// Using
=======================================================================
using namespace boost::python;
// Declarations
================================================================
namespace {
struct B_Wrapper: B
{
B_Wrapper(PyObject* py_self_, const B& p0):
B(p0), py_self(py_self_) {}
B_Wrapper(PyObject* py_self_):
B(), py_self(py_self_) {}
void Update(Data& p0) {
call_method< void >(py_self, "Update", p0);
}
PyObject* py_self;
};
}// namespace
// Module
======================================================================
BOOST_PYTHON_MODULE(PysteError)
{
class_< Data >("Data", init< >())
.def(init< const Data& >())
.def_readwrite("a", &Data::a)
;
scope* B_scope = new scope(
class_< B, boost::noncopyable, B_Wrapper >("B",
init< >())
.def("Update", pure_virtual(&B::Update))
);
register_ptr_to_python< boost::shared_ptr< B >
>();
delete B_scope;
class_< C >("C", init< >())
.def(init< const C& >())
.def("SetBptr", &C::SetBptr,
with_custodian_and_ward< 1, 2 >())
.def("Update", &C::Update)
.def("GetData_a", &C::GetData_a)
;
class_< D, bases< B > >("D", init< >())
.def(init< const D& >())
;
}
Here is the test code:
Expected 10 (good)
>>> from PysteError import *
>>> c = C()
>>> d = D()
>>> c.SetBptr(d)
>>> c.Update()
>>> print c.GetData_a()
10
Expected -1 (bad)
>>> class E(B):
... def Update(self,data):
... data.a = -1
...
>>> e = E()
>>> cc = C()
>>> cc.SetBptr(e)
>>> cc.Update()
>>> print cc.GetData_a()
0
Expected -1 (good)
>>> data = Data()
>>> e.Update(data)
>>> print data.a
-1
Hope this exposes the problem better. I honestly
don't have any idea why this doesn't work. Not even a
clue where to start looking for a bug.
Alexis
Programming Tutorial:
In Python: To do this, do this
In Perl: To do this, do this or this or this or this...
In C: To do this, do this, but be careful
In C++: To do this, do this, but don't do this, be careful of this, watch out for this, and whatever you do, don't do this
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
More information about the Cplusplus-sig
mailing list