DrTarr
DrTarr

Reputation: 952

Binding static member function as callback

I'm trying to use std::bind to use a member function as a callback to sigaction in the termios.h header. I understand special care needs taken with member functions and have read and followed the examples here and here, with no such luck.

Because I can pass through a static function, I thought if I left the function static, added a second variable as a pointer to itself (this), I would be good, but no such luck:

// In SerialListener.h
static void callback(int status, SerialListener *ptr);

// In the serial listener constructor

// Set callback
auto cb = std::bind(&SerialListener::callback, std::placeholders::_1, this);
sigAct_.sa_handler = cb;

But the error is as follows:

error: cannot convert ‘std::_Bind<void (*std::_Placeholder<1>, SerialListener*))(int, SerialListener*)>’ to ‘__sighandler_t {aka void (*)(int)}’ in assignment sigAct_.sa_handler = cb;

I also tried the variation in the second example w/o static implementation:

// In SerialListener.h
void callback(int status);

// In the serial listener constructor

// Set callback
auto cb = std::bind(&SerialListener::callback, this, std::placeholders::_1);
sigAct_.sa_handler = cb;

Which produces...

error: cannot convert ‘std::_Bind<std::_Mem_fn<void (SerialListener::*)(int)>(SerialListener*, std::_Placeholder<1>)>’ to ‘__sighandler_t {aka void (*)(int)}’ in assignment sigAct_.sa_handler = cb;

Errors look pretty similar, looks like it can't implicitly convert the bind to the handler it needs, but when I look at it from a perspective of input types and return types it should work. What am I missing?

Upvotes: 2

Views: 1971

Answers (1)

user7860670
user7860670

Reputation: 37468

Neither lambda or bind can help you to set a function not matching signal handler signature as a signal handler. Note that signal handler function signature does not provide any means to pass a class instance through opaque pointer. The best you can do is to store a pointer to handling context object at some static variable:

SerialListener * p_listener;

void On_Signal(int signal_code)
{
    if(p_listener)
    {
         p_listener->DealWith(signal_code); // calling member function
    }
}

p_listener= &my_listener;

sigAct_.sa_handler = &On_Signal;

Also note that depending on nature of signal the range of actions allowed in signal handler may be very limited.

Upvotes: 2

Related Questions