I have a solution that works for this, although it'd be cleaner if I could get the signal caught in Python rather than C++.
One thing I didn't mention before is that MyObject is a singleton, so I'm getting it with MyObject.getObject()
In Python, I've got:
def signalHandler( signum ) :
if signum == signal.SIGINT :
MyObject.getObject().stop()
def main() :
signal.signal( signal.SIGINT, handle_interrupt )
myObject = MyObject.getObject()
myObject.addSignalHandler( signal.SIGINT, signalHandler )
myObject.start()
In my C++ code, in an area that shouldn't know anything about Python, I have:
class MyObject
{
public :
void addSignalHandler( int signum, void (*handler)( int, void* ), void *data = nullptr );
void callSignalHandler( int signum );
private :
std::map<int, std::pair<void (*)( int, void* ), void*> > m_signalHandlers;
}
void signalCallbackHandler( int signum )
{
MyObject::getObject()->callSignalHandler( signum );
}
void MyObject::addSignalHandler( int signum, void (*handler)( int, void* ), void *data )
{
m_signalHandlers.insert( std::pair<int, std::pair<void (*)( int, void* ), void *> >( signum, std::make_pair( handler, data ) ) );
signal( signum, signalCallbackHandler );
}
void MyObject::callSignalHandler( int signum )
{
std::map<int, std::pair<void (*)( int, void* ), void*> >::iterator handler = m_signalHandlers.find( signum );
if( handler != m_signalHandlers.end() )
{
handler->second.first( signum, handler->second.second );
}
}
And then in my Python bindings:
void signalHandlerWrapper( int signum, void *data )
{
if( nullptr == data )
{
return;
}
PyObject *func = (PyObject*)( data );
if( PyFunction_Check( func ) )
{
PyObject_CallFunction( func, "i", signum );
}
}
void addSignalHandlerWrapper( MyObject *o, int signum, PyObject *func )
{
Py_INCREF( func );
if( PyFunction_Check( func ) )
{
o->addSignalHandler( signum, &signalHandlerWrapper, func );
}
}
What I don't have, which I should add, is something in addSignalHandlerWrapper() that will check if there was already something fo that signal number, and if so, get it and decrement the reference before adding the new one. I haven't done this yet, as this functionality is only used for ending the program, but for completeness, it should be put in place.
Anyway, as I said at the start, this is more involved than it could be. It also only works as I have a singleton that can keep track of the function pointers.