|
List Info
Thread: c++ to python object conversion problem
|
|
| c++ to python object conversion problem |
  Austria |
2007-03-03 13:05:25 |
hi all,
i've wrapped a simple c++ class with boost python, which
looks like
this:
class simple: boost::noncopyable{};
an instance of this class (or a derived one) is allocated
from python
and a pointer is stored in a class with a virtual function:
class callback: boost::noncopyable
{
virtual void overloadme(simple const &) = 0
void run(void) { this->overloadme(s_); }
void set(simple * s) {s_ = s;}
simple * s_;
};
this callback class is wrapped like it's described in the
tutorial:
class cbwrapper: callback, wrapper<callback>
{
virtual void overloadme(simple const & s) {
this->get_override("overloadme")(s);
}
};
callback::run is called from the c++ code later in the
program
asynchronously. however, when trying to call the overridden
function,
the program crashes:
> 0 PyErr_Restore PC=0xb7f30a9f, FP=0xb45461c8
[/usr/lib/libpython2.4.so.1.0]
1 PyErr_SetObject PC=0xb7f30b30, FP=0xb45461c8
[/usr/lib/libpython2.4.so.1.0]
2
_ZNK5boost6python9converter12registration9to_pythonEPVKv
PC=0xb519c4d6, FP=0xb45461c8
[/usr/lib/libboost_python-mt.so.1.33.1]
3
_ZN5boost6python9converter6detail18arg_to_python_baseC2EPVKv
RKNS1_12registrationE PC=0xb51accdf, FP=0xb45461e8
[/usr/lib/libboost_python-mt.so.1.33.1]
4
boost::python::converter::detail::value_arg_to_python<sim
ple>::not-in-charge value_arg_to_python PC=0xb678648b,
FP=0xb4546208
[/usr/include/boost/python/converter/arg_to_python.hpp#209]
5
boost::python::converter::arg_to_python<simple>::arg_t
o_python PC=0xb67864b5, FP=0xb4546228
[/usr/include/boost/python/converter/arg_to_python.hpp#256]
6 boost::python::override::operator ()<simple>
PC=0xb67864e0, FP=0xb4546268
[/usr/include/boost/python/override.hpp#138]
the instance of the wrapped object is still valid, but the
conversion
from the c++ object to the python object seems to be the
reason of the
crash ...
any idea, what i am missing?
thanks, tim
--
tim klingt.org ICQ: 96771783
http://tim.klingt.org
Just what the hell is the experimental tradition?
Morton Feldman
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: c++ to python object conversion
problem |

|
2007-03-03 13:21:25 |
On 3/3/07, Tim Blechmann <tim klingt.org> wrote:
> hi all,
>
> i've wrapped a simple c++ class with boost python,
which looks like
> this:
>
> class simple: boost::noncopyable{};
>
> an instance of this class (or a derived one) is
allocated from python
> and a pointer is stored in a class with a virtual
function:
>
> class callback: boost::noncopyable
> {
> virtual void overloadme(simple const &) = 0
> void run(void) { this->overloadme(s_); }
> void set(simple * s) {s_ = s;}
> simple * s_;
> };
>
> this callback class is wrapped like it's described in
the tutorial:
>
> class cbwrapper: callback, wrapper<callback>
> {
> virtual void overloadme(simple const & s) {
>
this->get_override("overloadme")(s);
I think that the problem in this line. By default
Boost.Python pass copy of the
object to the "override" function. In this case
"simple" is noncopyable.
( I don't understand why you didn't get compile time error
).
In my opinion you should change
this->get_override("...")(s)
to
this->get_override( ... )( boost::ref(s) )
P.S. Also you didn't specified how you exposed the classes
to Python.
P.S. Py++ is aware of this and would generate the right from
the beginning
--
Roman Yakovenko
C++ Python language binding
http://www.language-
binding.net/
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: c++ to python object conversion
problem |
  Austria |
2007-03-04 07:37:01 |
hi roman ... thanks for your hint
i've added the wrapper code below the classes:
> > class simple: boost::noncopyable{};
class_<simple,
boost::noncopyable>("simple");
> > an instance of this class (or a derived one) is
allocated from python
> > and a pointer is stored in a class with a virtual
function:
> >
> > class callback: boost::noncopyable
> > {
> > virtual void overloadme(simple const &) =
0
> > void run(void) { this->overloadme(s_); }
> > void set(simple * s) {s_ = s;}
> > simple * s_;
> > };
> >
> > this callback class is wrapped like it's described
in the tutorial:
> >
> > class cbwrapper: callback,
wrapper<callback>
> > {
> > virtual void overloadme(simple const & s)
{
> >
this->get_override("overloadme")(s);
class_<cbwrapper,
boost::noncopyable>("callback")
.def("set", &cbwrapper::set)
.def("overloadme",
&cbwrapper::overloadme)
;
> I think that the problem in this line. By default
Boost.Python pass copy of the
> object to the "override" function. In this
case "simple" is noncopyable.
> ( I don't understand why you didn't get compile time
error ).
> In my opinion you should change
> this->get_override("...")(s)
> to
> this->get_override( ... )( boost::ref(s) )
i tried this ... however python is crashing now:
> 0 PyFrame_New PC=0xb7e2c81a, FP=0xb44aee68
[/usr/lib/libpython2.4.so.1.0]
1 PyEval_EvalCodeEx PC=0xb7e79b74, FP=0xb44aeee8
[/usr/lib/libpython2.4.so.1.0]
2 PyClassMethod_New PC=0xb7e2d81d, FP=0xb44aef48
[/usr/lib/libpython2.4.so.1.0]
3 PyObject_Call PC=0xb7e14a35, FP=0xb44aef68
[/usr/lib/libpython2.4.so.1.0]
4 PyClass_IsSubclass PC=0xb7e1b05d, FP=0xb44af1b8
[/usr/lib/libpython2.4.so.1.0]
5 PyObject_Call PC=0xb7e14a35, FP=0xb44af1d8
[/usr/lib/libpython2.4.so.1.0]
6 PyEval_CallObjectWithKeywords PC=0xb7e73d26,
FP=0xb44af1f8 [/usr/lib/libpython2.4.so.1.0]
7 PyEval_CallFunction PC=0xb7e94207, FP=0xb44af228
[/usr/lib/libpython2.4.so.1.0]
8 boost::python::override::operator
()<boost::reference_wrapper<const simple> >
PC=0xb66f0712, FP=0xb44af268
[/usr/include/boost/python/override.hpp#138]
> P.S. Py++ is aware of this and would generate the right
from the beginning
... unfortunately, gccxml doesn't like my c++ code :/
any other hints or workarounds?
thanks ... tim
--
tim klingt.org ICQ: 96771783
http://tim.klingt.org
A paranoid is a man who knows a little of what's going on.
William S. Burroughs
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: c++ to python object conversion
problem |

|
2007-03-04 08:21:29 |
On 3/4/07, Tim Blechmann <tim klingt.org> wrote:
> hi roman ... thanks for your hint
>
> i've added the wrapper code below the classes:
>
> > > class simple: boost::noncopyable{};
>
> class_<simple,
boost::noncopyable>("simple");
>
> > > an instance of this class (or a derived one)
is allocated from python
> > > and a pointer is stored in a class with a
virtual function:
> > >
> > > class callback: boost::noncopyable
> > > {
> > > virtual void overloadme(simple const
&) = 0
> > > void run(void) { this->overloadme(s_);
}
> > > void set(simple * s) {s_ = s;}
> > > simple * s_;
> > > };
> > >
> > > this callback class is wrapped like it's
described in the tutorial:
> > >
> > > class cbwrapper: callback,
wrapper<callback>
> > > {
> > > virtual void overloadme(simple const &
s) {
> > >
this->get_override("overloadme")(s);
>
> class_<cbwrapper,
boost::noncopyable>("callback")
> .def("set", &cbwrapper::set)
A problem could also be here, you have to set call
policies:
http://boost.org/li
bs/python/doc/tutorial/doc/html/python/functions.html#python
.call_policies
Also, creating small and **complete** is much better way to
get help.
--
Roman Yakovenko
C++ Python language binding
http://www.language-
binding.net/
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| Re: c++ to python object conversion
problem |
  Austria |
2007-03-04 08:48:25 |
hi roman,
i just figured out, that it was a simple python threading
issue, because
the c++ thread hasn't been synchronized with python.
after guarding the calls to the override object by a
PyGILState_Ensure()/Release() pair, it works flawless!
cheers ... tim
On Sun, 2007-03-04 at 16:21 +0200, Roman Yakovenko wrote:
> On 3/4/07, Tim Blechmann <tim klingt.org> wrote:
> > hi roman ... thanks for your hint
> >
> > i've added the wrapper code below the classes:
> >
> > > > class simple: boost::noncopyable{};
> >
> > class_<simple,
boost::noncopyable>("simple");
> >
> > > > an instance of this class (or a derived
one) is allocated from python
> > > > and a pointer is stored in a class with
a virtual function:
> > > >
> > > > class callback: boost::noncopyable
> > > > {
> > > > virtual void overloadme(simple const
&) = 0
> > > > void run(void) {
this->overloadme(s_); }
> > > > void set(simple * s) {s_ = s;}
> > > > simple * s_;
> > > > };
> > > >
> > > > this callback class is wrapped like it's
described in the tutorial:
> > > >
> > > > class cbwrapper: callback,
wrapper<callback>
> > > > {
> > > > virtual void overloadme(simple const
& s) {
> > > >
this->get_override("overloadme")(s);
> >
> > class_<cbwrapper,
boost::noncopyable>("callback")
> > .def("set", &cbwrapper::set)
>
> A problem could also be here, you have to set call
policies:
> http://boost.org/li
bs/python/doc/tutorial/doc/html/python/functions.html#python
.call_policies
>
> Also, creating small and **complete** is much better
way to get help.
>
--
tim klingt.org ICQ: 96771783
http://tim.klingt.org
Life is really simple, but we insist on making it
complicated.
Confucius
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
| yet another conversion problem (was:
Re: c++ to python object conversion
problem) |
  Austria |
2007-03-04 11:50:04 |
ok ... now i'm facing the problem, that a class derived from
a c++ class
is converted to the c++ base class, in a python callback:
the c++ classes are:
struct simple: boost::noncopyable
{
};
struct holder: boost::noncopyable
{
simple * s_;
void set(simple * s)
{
s_ = s;
}
void run(void)
{
this->ping(s_);
}
virtual void ping(simple * s) = 0;
};
struct holder_wrapper:
holder,
wrapper<holder>
{
virtual void ping(simple * s)
{
this->get_override("ping")(boost::ref(s));
}
};
which are wrapped:
class_<simple,
boost::noncopyable>("simple");
class_<holder_wrapper,
boost::noncopyable>("holder")
.def("set", &holder_wrapper::set)
.def("run", &holder_wrapper::run)
.def("ping",
pure_virtual(&holder_wrapper::ping))
;
from python, i derive new classes and implement the virtual
function
holder::ping:
class simple_d(simple):
def __init__(self, i):
simple.__init__(self)
self.i = i
class holder_d(holder):
def __init__(self):
holder.__init__(self)
def ping(self, s):
assert(isinstance(s, simple))
assert(isinstance(s, simple_d))
print s.i
when i call it like this the instant s in the python code,
the second
assert statement fails. the object is not handled as
simple_d, but as
simple:
s = simple_d(53)
h = holder_d()
h.set(s)
h.run()
is there any way to "upcast" the instance s from
simple to simple_d?
thanks again!
tim
--
tim klingt.org ICQ: 96771783
http://tim.klingt.org
Linux is like a wigwam: no windows, no gates, apache inside,
stable.
_______________________________________________
C++-sig mailing list
C++-sig python.org
http:
//mail.python.org/mailman/listinfo/c++-sig
|
|
[1-6]
|
|