[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