在class Foo
我有两种方法,assign_handler()
和call_handler()
。
实际的处理程序代码位于main.cpp
do_this()
。 do_this()
使用main.cpp
,
我认为Foo必须有一个函数指针作为成员,它将在assign_handler()
中分配,这就是我所做的。但是,我无法从assign_handler()
调用do_this()
,即调用call_handler()
。
注意:call_handler()
本身由sigaction
中的Foo
拨打。
编辑:我按照评论中的建议尝试制作MCVE。我使用gedit创建文件并在命令行中使用g ++编译它。代码有效。但是在我的Eclipse项目中,我得到了代码的内联注释中显示的错误。
MCVE:
//Foo.h
class Foo{
public:
void (*funptr)(void);
void call_handler();
void assign_handler (void(*func1)(void));
Foo(){};
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
funptr();//error: invalid use of member Foo::funptr in static member function; from this location
//or
//this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
Foo foo;
foo.assign_handler(do_this);
foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
int x;
cin>>x;
}
void do_this(void){
cout<<"done"<<endl;
}
答案 0 :(得分:2)
我将我的答案分成两部分。首先我会尝试回答你的问题,然后我会尝试告诉你你真正想做的事情。
您的问题是如何为成员变量分配函数指针,然后从静态成员函数调用它。由于函数指针是类的成员,因此您还需要一个指向该类的指针才能调用该函数指针。实现此目的的一种方法是向类中添加一个静态成员,该成员包含指向类的(单个)实例的指针。既然您表示将使用它作为信号处理程序,那么您无论如何都不想使用多个处理程序。
所以,像这样:
//Foo.h
class Foo{
public:
static void call_handler();
void assign_handler (void(*func1)(void));
Foo() {
ms_instance = this;
};
private:
void (*funptr)(void);
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
ms_instance->funptr();
}
更通用的方法是存储一个函数对象:
//Foo.h
#include <functional>
#include <utility>
class Foo{
public:
static void call_handler();
template<typename func>
void assign_handler (func&& handler)
{
m_handler = std::forward(handler);
}
Foo() {
ms_instance = this;
};
private:
std::function<void(void)> m_handler;
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::call_handler(){
ms_instance->m_handler();
}
这样你可以分配许多不同的东西作为处理程序:
// Function pointers
foo.assign_handler(do_this);
// Lambdas
foo.assign_handler([]() { /* do something */ });
// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));
现在,当您要处理信号时,实际想要做的事情有点复杂。请记住,信号处理程序只能调用某些函数(async-signal-safe functions) - 否则事情可能会变得难看。因此,你应该执行一个称为自管技巧的常见技巧。基本上你应该有一个接收信号的信号处理程序,但只在管道上调用write
,信号编号作为要发送的数据。然后,您的代码中有另一个位置在管道上调用select
,然后read
来读取信号编号。然后调用适当的处理函数,然后允许它做你喜欢的任何事情。
这方面的一个例子是:http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html
请注意,以跨平台方式实现这一点可能有点棘手,尤其是在多线程的情况下。