I have a class Myclass:
in Myclass.h file:
class{
private:
int sd;
int sd2;
public:
void func(int sd, short op, void *ptr);
void start();
};
in Myclass.cpp file:
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 );
.....
}
...
}
in main.cpp
int main(){
Myclass obj;
....
obj.start();
....
}
in start(), the event_set need a function of void(*func)()
type as argument,but func() is of void Myclass::(*func)()
type, so I define a new function something like below (the codes are not correct, but just show what I expect):
void call_func(int sd, short op, void *ptr){
Myclass::func(int sd, short op, void *ptr);
}
however, I'm at a loss where to delcare and define call_func()
so that the Myclass::start()
can use call_func
as argument and call_func()
can call Myclass::func()
This is a known problem. Since pointers to class members are not regular pointers, one can not use class member functions in naive callbacks, which expect a simple function pointer.
A solution is to make a callback function static
, often private
, and call the corresponding class function using the callback argument. In your case, it would look like following:
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);
}
};
EDIT
Fixed messed up start()
and func()
.
I'm at a loss where to delcare and define
call_func()
so that theMyclass::start()
can usecall_func
as argument andcall_func()
can callMyclass::func()
You can put this all in your Myclass.cpp file, above the definition of 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)){
...
...
}
One other thing, with callback functions, the void* ptr
is how you can pass a pointer to some data that the callback function will use. If you don't need anything like that then you don't need to be calling a non-static member function as the callback and you could simplify things. But to call non-static member function the way you're describing, you need an object to call it on, and that's what you would pass as the 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)){
...
...
}
the last argument of
event_set()
is still needed to be used for a pointer to an additional structure, so it can't bethis
You need to pass this
somehow or you can't call a member function, so if you have another structure you need to think about how to pass both.
Can the other structure or a pointer to it be a member of the object? If so, then do that and pass this
as the void *ptr
.
Another option is to define a struct
just for passing the data through the callback:
struct callback_params {
Myclass *c;
other_struct *s;
};
But you have to create this callback_params
struct somewhere where it will live long enough for the callback to be able to receive it, which can be tricky.
My old tablet didn't load the code sections of the question correctly and I miss important parts of the question...
Leaving here just as sake of completeness - maybe this can be util for someone else
SORRY
I don't know the complete stuff that you're doing but in this cases, if i don't need interface with old code I will go for std::function
for sure.
But if is absolutely needed the pointers stuff, I generally do:
_func_call_wrapper_(...)
//This is a wrapper neeeded for... void __func_call_wrappper_(..);
Refs: ccpreference
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.