Когда я использую 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;
}
В 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 ++.
Единственное решение для обработчика сигнала — это своего рода глобальная переменная.
@SJL предоставил отличное объяснение того, почему это не работает, и предлагает обходной путь в стиле Си.
Если вы можете использовать Boost, boost::asio::signal_set
может использоваться для обработки сигналов в стиле C ++. async_wait
функция может получить лямбду, связанный указатель на функцию-член или любой другой вызываемый тип с соответствующей сигнатурой.