My library offers a callback point where my library users can register to get information. The general form of the callback is an int
followed by various parameters whose type depend on the int value. Therefore, I defined the callback type and the function to set it as follows.
typedef void (* callback_func_t)(int type, ...);
void set_callback_func(callback_func_t callback);
Within my library, I am calling this function all throughout, being the user set function, or the default one I am providing. It works.
Now, I'd like to add a level of indirection, to be able to call several registered callbacks. The trouble is that my internal callback function that still takes ellipsis parameters, also have to call the callback function with ellipsis. As a consequence, my internal function has to interpret the type
, unpack the parameters from the va_list
and give them as parameters to the callbacj function.
void internal_callback(int type, ...) {
va_list args;
va_start(args, type);
switch (type) {
case 0: call_callback(type, va_arg(args, int)); break;
// ...
}
va_end(args);
}
But then, in the user's implementation of the callback, there will also be the same va_list
usage, and interpretation of the arguments, according to the value of type
. The solution is to pass directly the va_list
as an argument to the callback function, making the implementation of the internal callback function obvious.
typedef void (* callback_func_t)(int type, va_list args);
My question is: is it good practice to define a callback function type that takes va_list
as argument? I can define my callback function type as above, but what are the pros and cons compared to the definition at the top?