[C++-sig] Deriving Python function from C++ base class with pure virtual function
Paul F. Kunz
Paul_Kunz at slac.stanford.edu
Sat Nov 13 10:53:18 CET 2004
I'm deriving a Python class from a C++ class with both concrete and
pure virtual functions. I written a FunctionWrap C++ class that
implements the pure virtual function, operator() (double) by invoking
the call_method. Then my Python class looks like...
from hippo import AbsFunction
class Linear ( AbsFunction ) :
def __init__ ( self ) :
AbsFunction.__init__(self)
self.initialize ()
def initialize ( self ) :
self.setName ( 'linear' )
self.setParmNames ( [ 'Intercept', 'Slope' ] )
self.setParameters ( [ intercept, slope ] )
def valueAt ( self, x ) :
parms = self.getParameters ()
return x * parms[1] + parms[0]
where AbsFunction is the Python name for the C++ base class and all
the set and get functions are implemented in the C++ base class. The
FunctionWrap::operator ()(double) is implemented to call the Python
valueAt method. All this works within a Python script.
However, I want to also call operator()(double) from C++ code in a
different thread from the Python main thread. This other thread is
started with Qt's QThread class. When I do this I get to
FunctionWrap::operator()(double) and then seg fault with the following
back trace in gdb...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1117711152 (LWP 4144)]
0x080fc20c in PyFrame_New (tstate=0x0, code=0x4018dce0,
globals=0x4015d79c,
locals=0x0) at Objects/frameobject.c:540
(gdb) bt
#0 0x080fc20c in PyFrame_New (tstate=0x0, code=0x4018dce0,
globals=0x4015d79c, locals=0x0) at Objects/frameobject.c:540
#1 0x080b7353 in PyEval_EvalCodeEx (co=0x4018dce0,
globals=0x4015d79c,
locals=0x4018dce0, args=0x406396b8, argcount=2, kws=0x0,
kwcount=0,
defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2455
#2 0x080fd955 in function_call (func=0x405ed48c, arg=0x406396ac,
kw=0x0)
at Objects/funcobject.c:504
#3 0x0805b8c7 in PyObject_Call (func=0x0, arg=0x4018dce0,
kw=0x4018dce0)
at Objects/abstract.c:1755
#4 0x08064aae in instancemethod_call (func=0x4018dce0,
arg=0x406396ac,
kw=0x4018dce0) at Objects/classobject.c:2433
#5 0x0805b8c7 in PyObject_Call (func=0x0, arg=0x4018dce0,
kw=0x4018dce0)
at Objects/abstract.c:1755
#6 0x080b103b in PyEval_CallObjectWithKeywords (func=0x4018dce0,
arg=0x4018ce4c, kw=0x405ec5f4) at Python/ceval.c:3346
#7 0x080d89e3 in PyEval_CallMethod (obj=0x4018dce0,
methodname=0x4018dce0 "\001", format=0x4018dce0 "\001")
at Python/modsupport.c:506
#8 0x407e5708 in boost::python::call_method<double, double> (
self=0x4018dce0, name=0x4018dce0 "\001", a0=@0x4018dce0) at
handle.hpp:64
#9 0x407e4de7 in FunctionWrap::operator() (this=0x4018dce0, x=0)
at ../../hippodraw/python/FunctionWrap.cxx:111
Apparently I have threading problems but don't know how to
procede. I tried wrapping call_method with
Py_ALLOW_THREADS_BEGIN/END, but that seg faults immediately.
Should I start the second thread with Python's own thread class?
Is there some Python C API functions I could call to read the Python
object to be called from this second thread? Any suggestions /
advise would be appreciated.
More information about the Cplusplus-sig
mailing list