c++ - 如何设置 (*sa_handler)(int) 指向作为类成员的函数的指针?(无效使用非静态成员函数)
问题描述
我不是 C++ 专家,我正在尝试创建一个类来处理终端上按下的 ctrl+C。
在我开始将它们移动到 SignalHandler 类之前,我的方法正在工作。
看起来我无法将 sigaction.sa_action 设置为:
sigIntHandler.sa_handler = SomeClass->someMethod(int s);
就像我在 C 中一样。
sigIntHandler.sa_handler = someMethod(int s);
编译器说:
signals.cpp: In constructor ‘SignalHandler::SignalHandler()’:
signals.cpp:5:39: error: invalid use of non-static member function
registerSignalHandler(ctrlCHandler);
^
我的代码有什么问题?
我想我必须将我的类成员函数转换为这样的东西:(*sa_handler)(int)
.
cpp文件:
#include "signals.h"
SignalHandler::SignalHandler() {
isSigtermReceived = false;
registerSignalHandler(ctrlCHandler);
}
SignalHandler::~SignalHandler() {
}
// private
void SignalHandler::registerSignalHandler(void (*handler)(int)){
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
}
void SignalHandler::ctrlCHandler (int s) {
using namespace std;
cout << endl << "Caught signal " << s << ". Exiting." << endl;
isSigtermReceived = true;
}
h 文件:
#ifndef SIGNALS_H
#define SIGNALS_H
#include <signal.h> // ctrl-c
#include <iostream>
class SignalHandler {
public:
SignalHandler();
virtual ~SignalHandler();
bool isSigtermReceived;
void registerSignalHandler(void (*hnd)(int));
private:
void ctrlCHandler(int s);
};
#endif /* SIGNALS_H */
这是我试图分配sa_handler字段的结构:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
解决方案
您不能将成员函数转换为函数指针。
尽管有实际的语义,你可以认为成员函数有一个隐藏的this
引用,它不能作为自由函数指针传递。
最简单的解决方案是使用桥接方法来解决这个问题,例如:
class SignalHandlerDispatcher {
private:
static SignalHandler* _handler;
public:
static void setHandler(SignalHandler* handler) { _handler = handler; }
static void sa_handler(int v) { _handler->SomeMethod(v); }
};
所以现在你可以SignalHandlerDispatcher::sa_handler
用作你的回调,因为它是static
.
推荐阅读
- django - 用python打开没有文本的pdf
- mysql - 无法从 Workbench 访问 CentOS 上的 MySQL 服务器
- c# - c# 在表单之间导航
- hibernate - 非法尝试将集合与两个打开的会话相关联-Dropwizard 与 Hibernate
- azure - Azure 函数不生成 extensions.json
- c++ - 在 C++ 中,发生故障后是否需要 stream.clear()?
- javascript - 使用 Polymer.dom(this.root).querySelector 在 Polymer 元素中找不到复选框元素
- grails - Postgresql 和 Grails 3.3.8 的默认字符串大小似乎是 20 个字符
- json - 使用 Express 返回特定的 JSON 对象
- python - 如何在 SQLAlchemy DB URI 中定位 PostgreSQL 模式?