Ошибка обработки сигнала

Когда я использую my_handler в качестве функции, там нет ошибки, но я не могу, потому что я должен использовать другой метод там.

Если я строю код ниже:
ошибка: недопустимое использование члена functi
на (ты забыл ‘()’?)

Это моя первая программа на C ++

void Client::my_handler(int s){
if (s == SIGINT){
printf("SIGINT\n");
// here I have to use stop_thread method
}
}int main (int argc, const char **argv) {
Client client(argc, argv);
client.before_start();

struct sigaction sigIntHandler;

sigIntHandler.sa_handler = (__sighandler_t) client.my_handler; //error here
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);

client.run();

return 0;
}

1

Решение

В C ++ функция-член (функция, связанная с экземпляром класса, такая как client.my_handler здесь) не то же самое, что обычная функция (что-то вроде int main(int arg, const char** argv) Вот). Вот почему вы не можете бросить client.my_handler в __sighandler_t,

Client::my_handler имеет скрытый параметр, Client*, Так что на самом деле, это подпись (с определенной точки зрения) выглядит void my_handler(Client* this, int s), C ++ делает некоторые вещи за кулисами, чтобы вы могли ссылаться на переменные this без необходимости делать this-> (большую часть времени). И когда вы делаете что-то вроде звонка

client.my_handler(SIGINT)

C ++ переводит это

my_handler(&client, SIGINT)

Может быть, теперь вы можете увидеть проблему: __sighandler_t псевдоним для указателя функции, но client.my_handler действительно два указатели: указатель функции для my_handler и указатель на client,

Обработчик сигнала принимает только указатель функции, а не более общий объект функции (который является указателем функции плюс некоторые другие данные). Обработка сигналов из C, но объекты функций из C ++.

Единственное решение для обработчика сигнала — это своего рода глобальная переменная.

4

Другие решения

@SJL предоставил отличное объяснение того, почему это не работает, и предлагает обходной путь в стиле Си.

Если вы можете использовать Boost, boost::asio::signal_set может использоваться для обработки сигналов в стиле C ++. async_wait функция может получить лямбду, связанный указатель на функцию-член или любой другой вызываемый тип с соответствующей сигнатурой.

0

По вопросам рекламы [email protected]