我有一个Myclass类:
在Myclass.h文件中:
class{
private:
int sd;
int sd2;
public:
void func(int sd, short op, void *ptr);
void start();
};
在Myclass.cpp文件中:
void Myclass::start(){
struct arg_t *arg = (struct arg_t *)malloc(sizeof(struct arg_t));
....
event_set(ev, sd, EV_READ, call_func, arg ); //this is a library API, which trigger the callback of call_func(sd, op, arg);
}
void Myclass::func(int sd, short op, void *ptr)){
...
if(some_conditions){
struct arg_t *arg = (struct arg_t *)malloc(sizeof(struct arg_t))
....
event_set(ev, sd2, EV_READ, call_func, arg );
.....
}
...
}
在main.cpp
中int main(){
Myclass obj;
....
obj.start();
....
}
在start()中,event_set需要void(*func)()
类型的函数作为参数,但是func()是void Myclass::(*func)()
类型的,所以我定义了一个类似于下面的新函数(代码不是正确,但只是展示我的期望):
void call_func(int sd, short op, void *ptr){
Myclass::func(int sd, short op, void *ptr);
}
然而,我无法在哪里进行delcare并定义call_func()
,以便Myclass::start()
可以使用call_func
作为参数,call_func()
可以调用Myclass::func()
}
答案 0 :(得分:2)
这是一个已知问题。由于指向类成员的指针不是常规指针,因此在初始回调中不能使用类成员函数,这需要一个简单的函数指针。
解决方案是创建一个回调函数static
,通常是private
,并使用回调参数调用相应的类函数。在您的情况下,它将如下所示:
class C {
private:
int sd;
static void call_func(int sd, short op, void* ptr) {
C* obj = static_cast<C*>(ptr);
obj->func(sd, op);
}
public:
void func(int sd, short op);
void start() {
event_set(ev, sd, EV_READ, &call_func, this);
}
};
修改强>
修复了混乱start()
和func()
。
答案 1 :(得分:1)
我很遗憾在哪里进行delcare并定义
call_func()
,以便Myclass::start()
可以使用call_func
作为参数,call_func()
可以调用Myclass::func()
}
您可以将此全部放在Myclass.cpp文件中,高于Myclass :: start()的定义。“
#include <Myclass.h>
void call_func(int sd, short op, void *ptr){
Myclass::func(int sd, short op, void *ptr);
}
void Myclass::start(){
event_set(ev, sd, EV_READ, call_func, NULL ); //this is a library API, which trigger the callback of call_func(sd, op, NULL);
}
void Myclass::func(int sd, short op, void *ptr)){
...
...
}
另一件事,使用回调函数,void* ptr
是如何将指针传递给回调函数将使用的某些数据。如果你不需要这样的东西,那么你就不需要调用非静态成员函数作为回调,你可以简化一些事情。但是,要按照您描述的方式调用非静态成员函数,您需要一个对象来调用它,这就是您将void *ptr
传递的内容:
// Myclass.h
class Myclass {
private:
int sd;
public:
void func(int sd, short op); // no void*
void start();
};
// Myclass.cpp
#include <Myclass.h>
void call_func(int sd, short op, void *ptr){
assert(ptr != NULL);
static_cast<Myclass *>(ptr)->func(int sd, short op); // cast data to 'this' pointer
}
void Myclass::start(){
event_set(ev, sd, EV_READ, call_func, this ); // pass the 'this' pointer as data
}
void Myclass::func(int sd, short op)){
...
...
}
event_set()
的最后一个参数仍然需要用于指向其他结构的指针,因此它不能this
您需要以某种方式传递this
,否则您无法调用成员函数,因此如果您有其他结构,则需要考虑如何通过这两种结构。
其他结构或指向它的指针可以是对象的成员吗?如果是,请执行此操作并将this
作为void *ptr
传递。
另一种选择是定义struct
只是为了通过回调传递数据:
struct callback_params {
Myclass *c;
other_struct *s;
};
但是你必须在某个地方创建这个callback_params
结构,它的存活时间足够长,以便回调能够接收它,这可能很棘手。
答案 2 :(得分:-3)
我的旧平板电脑没有加载问题的代码部分
正确而且我错过了问题的重要部分......
离开这里只是为了完整 - 也许这可以是实用的
对于其他人
<强> SORRY 强>
我不知道你所做的全部事情,但在这种情况下,
如果我不需要与旧代码接口,我肯定会去std::function
。
但如果绝对需要指针,我通常会这样做:
_func_call_wrapper_(...)
//This is a wrapper neeeded for...
void __func_call_wrappper_(..);
参考文献: ccpreference