Обработчик сигналов как член класса

184
01 апреля 2018, 20:56

Пишу класс работающий с трафиком RS485 порта. При открытии порта я указываю функцию, вызываемую при наличии во входном буфере порта каких-то данных:

struct sigaction saio; /* definition of signal action */
fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); /* open the device to be non-blocking (read will return immediatly) */
if (fd <0) { perror(device);}
sigemptyset(&saio.sa_mask); /* install the signal handler before making the device asynchronous */
saio.sa_handler = signal_handler_IO;

Если функция - обработчик описана как обучная функция:

void signal_handler_IO (int status){
    if (read(fd,&buf,1)){
        std::cout << "I'm recieve byte\t" << std::hex << buf[0] << std::dec << std::endl;
    }
}

То проблем нет. Но если я эту функцию делаю членом класса, то возникают ошибки компиляции.

error: cannot convert ‘Rs485::signal_handler_IO’ from type ‘void (Rs485::)(int)’ to type ‘__sighandler_t {aka void (*)(int)}’

Я в C++ не очень силен и не понимаю что от меня хочет компилятор. Скажите пожалуйста, как мне сделать членом класса функцию-обработчик ?

Answer 1

Во-первых, sa_handler имеет тип void (*)(int), поэтому сделать можно будет не много.

Это либо стандартная функция, как в C,

void handler(int);
saio.sa_handler = &handler;

, либо анонимная функция без свободных переменных (начинающаяся с [])

saio.sa_handler = [](int sig){ /* ... */ };

, либо статический член класса

struct Saio {
    static void handler(int sig) { /* ... */ }
};
saio.sa_handler = &Saio::handler;

. При этом все три могут принимать лишь один аргумент типа int, а о контексте (инкапсулированном в объекте-обработчике состоянии) никто и не подумал.

Ну то есть все данные, нужные обработчику, либо предполагаются глобальными

std::ostream &os = std::cout;
struct Saio {
    static void handler(int sig) { os << "Signal #" << sig << std::endl; }
};

, либо во всяком случае статическими на уровне класса (Александреску пишет, что это и есть Monostate pattern):

class Saio {
    static int handlerData;
    static std::string moreHandlerData() { return "Hello" };
public:
    static void setData(int x) { handlerData = x; }
    static void handler(int sig) {
        os << moreHandlerData()
           << ", this is handler#" << handlerData << " speaking, I've got signal"
           << sig << std::endl;
    }
};
int Saio::handlerData = 42;
READ ALSO
error LNK2019: ссылка на неразрешенный внешний символ main в функции &ldquo;int __cdecl invoke_main(void)&rdquo; (?invoke_main@@YAHXZ)

error LNK2019: ссылка на неразрешенный внешний символ main в функции “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ)

Так как это должно быть приложение, то там должна быть функция int main(){}Возможно, ее роль выполняет функция go

315
Использование С/С++ в Python

Использование С/С++ в Python

Доброго времени, сутокМне надо надо написать функцию которую можно будет вызывать в Python 3

211
Как сравнить два типа ? С++

Как сравнить два типа ? С++

Мне надо сравнить два типаКак это сделать ? Допустим я беру из базы типы колонок

241
Copy-on-write и константные методы

Copy-on-write и константные методы

Есть вот такой код:

238