Misusing void to pass arbitrary arguments

2017/01/15

I came across the situation where I need to call a function passing a callback function and possible arguments for the callback function:

zthread_fork (zctx_t *ctx, zthread_attached_fn *thread_fn, void *args);

(from czmp)

Later my thread_fn will be called and args passed to it. And now I had to pass more than one argument to it. After hours of trying getting my head around it (and using an array of pointer) with a lot of help I came to a working example:

#include <stdio.h>

struct params_t
{
    void (*func)(int*);
    int* i;
};

void bla (int *i)
{
    printf("%d\n", *i);
}

void bar (void *args)
{
   struct params_t *argstruct = (struct params_t*) args;
   void (*func)(int *) = argstruct->func;
   int *num = argstruct->i;
   func(num);
}
int main ()
{
    // Function pointer of bla()
    int b = 100;
    // Put both variables into the struct
    struct params_t args;
    args.func = &bla;
    args.i = &b;
    bar(&args);
    return 0;
}

Bear in mind that this only works if you are in the process and thread, it may work with different threads but no one can guarantee the other thread still exists.