信号处理错误
Signal handling error
当我使用 my_handler 作为函数时没有错误,但我不能,因为我必须在那里使用另一种方法。
如果我在下面构建代码:
错误:成员函数的使用无效
on(你忘记了'()'吗?)
这是我的第一个 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++ 中,成员函数(与 class 实例关联的函数,例如此处的 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->
(大多数情况下)。当你做类似 call
的事情时
client.my_handler(SIGINT)
C++ 正在将其转换为
my_handler(&client, SIGINT)
也许现在你可以看到问题了:__sighandler_t
是函数指针的别名,但client.my_handler
实际上是两个指针:函数指针对于 my_handler
和指向 client
.
的指针
信号处理程序只接受一个函数指针,而不是一个更通用的函数对象(它是一个函数指针加上一些其他数据)。信号处理来自 C,但函数对象来自 C++。
信号处理程序的唯一解决方案是某种全局变量。
@SJL 很好地解释了为什么这不起作用,并提供了 C 风格的解决方法。
如果可以使用 Boost,boost::asio::signal_set
可以用于以更 C++ 风格处理信号。 async_wait
function 可以接收 lambda、绑定成员函数指针或任何其他具有适当签名的可调用类型。
当我使用 my_handler 作为函数时没有错误,但我不能,因为我必须在那里使用另一种方法。
如果我在下面构建代码: 错误:成员函数的使用无效 on(你忘记了'()'吗?)
这是我的第一个 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++ 中,成员函数(与 class 实例关联的函数,例如此处的 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->
(大多数情况下)。当你做类似 call
client.my_handler(SIGINT)
C++ 正在将其转换为
my_handler(&client, SIGINT)
也许现在你可以看到问题了:__sighandler_t
是函数指针的别名,但client.my_handler
实际上是两个指针:函数指针对于 my_handler
和指向 client
.
信号处理程序只接受一个函数指针,而不是一个更通用的函数对象(它是一个函数指针加上一些其他数据)。信号处理来自 C,但函数对象来自 C++。
信号处理程序的唯一解决方案是某种全局变量。
@SJL 很好地解释了为什么这不起作用,并提供了 C 风格的解决方法。
如果可以使用 Boost,boost::asio::signal_set
可以用于以更 C++ 风格处理信号。 async_wait
function 可以接收 lambda、绑定成员函数指针或任何其他具有适当签名的可调用类型。