c++ 如何设置(*sa_handler)(int)指针指向类成员函数?(非静态成员函数的使用无效)

xdnvmnnf  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(149)

我不是C++Maven,我试图创建一个类,处理在终端按下ctrl + C。
我的方法在我开始将它们移到SignalHandler类之前就可以工作了。
看起来我无法将www.example.com_action设置为:sigaction.sa_action to:

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);
};

http://man7.org/linux/man-pages/man2/sigaction.2.html

ego6inou

ego6inou1#

不能将成员函数转换为函数指针。
不管实际的语义如何,你可以认为一个成员函数有一个隐藏的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

相关问题