Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use a many-parameters function as callback function

I'm using a timer, in C, which is system-dependant (I cannot change its code). I can access it, among others, with this function :

void start_timer(int duration, void (*callback)(void*), void* arg);

So I can give to the timer a callback function and its void* argument.

The function I would like to use as callback is:

void send_message(ipaddr* source, ipaddr* destination, char* message);

I cannot directly give this function to start_timer, because it does not match the void (*)(void*) required type. As anonymous functions does not exist in C, I cannot use this solution (but it is what I would like to do):

start_timer(1000, void(*)(void* stuff){
    send_message(source, destination, message);
}, NULL);

So I must give a name to this function:

void call_send_message(void* stuff) {
    send_message(source, destination, message);
}
start_timer(1000, &call_send_message, NULL);

Is there a more beautiful way to call send_message function using start_timer?

like image 954
audeoudh Avatar asked Mar 24 '26 16:03

audeoudh


2 Answers

Create a struct, something like this:

struct args {
    ipaddr *source;
    ipaddr *destination;
    char *message;
};

and have your send_message function take void* argument, then you just cast it to a struct args type and from there you can access its members. If you can't edit it, then create a "wrapper" like your example:

So basically your function below

void call_send_message(void* stuff) {
    send_message(source, destination, message);
}

becomes

void call_send_message(void* stuff) {
    struct args *realstuff = (struct args *) stuff;
    send_message(realstuff->source, realstuff->destination, realstuff->message);
}
like image 84
Jite Avatar answered Mar 27 '26 12:03

Jite


1. Make a data structure to store your data.

typedef struct Data {
  ipaddr *src;
  ipaddr *dst;
  char   *msg;
} Data;

2. Make a wrapper that matches the signature and call inside the send_message function:

void wrapper(void *args) {
  Data *data = (Data*) args;
  send_message(data->src, data->dst, data->msg);

}

3. Call wrapper like below:

   start_timer(duration, &wrapper, your_data);
like image 37
101010 Avatar answered Mar 27 '26 12:03

101010