I have a program in which te type of function to be used has to be different according to a string (the mode). Suppose i want the functions in extfunc
to be initiated according to the value i write in some strings, that i have the following situation.
I have a number of functions
void f1_mod1(...)
{
//do domething
}
void f1_mod2(...)
{
//do something else
}
void f2_mod1(...)
{
//do something 2
}
void f2_mod2(...)
{
//do something 2
}
and I want them to be used according to some configurational strings fXn
, where X = 1, 2
, as in
void extfunc(...)
{
// ...
char *f1n = "mod1";
char *f2n = "mod2";
void (*__f1__)(), (*__f2__)();
__thefunctioniwouldlike(f1n, __f1__, f2n, __f2__);
// execute f1_mod1
__f1__(...);
// execute f2_mod2
__f2__(...);
}
where
void __thefunctioniwouldlike(char *f1n, void *__f1__, char *f2n, *__f2__)
{
if (strcmp(f1n, "mod1") == 0)
__f1__ = f1_mod1;
else if (strcmp(f1n, "mod2") == 0)
__f1__ = f1_mod2;
else
__f1__ = NULL;
if (strcmp(f2n, "mod1") == 0)
__f2__ = f2_mod1;
else if (strcmp(f1n, "mod2") == 0)
__f2__ = f2_mod2;
else
__f1__ = NULL;
}
is a function that takes the configurational strings and assign the function pointers to one of my functions above so that when they are called execute the assigned function.
For completeness:
fX_modX
are the functions that take certain arguments and do different stuff both based on the mod variable fXn
encoded in a string and __thefunctioniwouldlike
is a function that takes as argument the pointers to functions to initiate them according to the value of strings fXn
. How can i pass the pointer to pointers to void functions void (*__f1__)()
so that in the end executing __fX__
in extfunc
will execute fX_modY
or fX_modY
based on the assignment inside __thefunctioniwouldlike
?
Thanks in advance.
How can i pass the pointer to pointers to void functions
void (*__f1__)()
so that in the end executing__fX__
inextfunc
will executefX_modY
orfX_modY
based on the assignment inside__thefunctioniwouldlike
?
As ever, in C function arguments are passed by value. If you want a called function to modify an object that is local to the caller, then you must pass the address of that object to the function, and the function must modify it indirectly. That applies just the same when that object has pointer type, including function pointer type, as when it has any other type.
Type names can get pretty hairy, however, especially when function pointers are involved. Typedefs can help. I would recommend something along these lines:
// declare f1_func and f2_func as aliases for function types
typedef void (f1_func)(/* ... f1 parameters ... */);
typedef void (f2_func)(/* ... f2 parameters ... */);
// the actual functions must have parameter lists matching the expected ones
// for the corresponding typedefed function types
void mod1_f1(/* parameters */) {
// ...
}
void mod1_f2(/* parameters */) {
// ...
}
void mod2_f1(/* parameters */) {
// ...
}
void mod2_f2(/* parameters */) {
// ...
}
// Functions cannot be handled as objects. You need to use function pointers, instead,
// such as a f1_func * or a f2_func *.
//
// But then you need a second level of indirection to allow a function to manipulate
// function pointers that are local to the caller.
void set_module_functions(const char *f1_module, f1_func **f1,
const char *f2_module, f2_func **f2) {
// Note: Function names such as mod1_f1 are automatically converted to pointers
// in some case:
*f1 = mod1_f1;
// in another case:
*f1 = mod2_f1;
// in some case:
*f2 = mod1_f2;
// in another case:
*f2 = mod2_f2;
}
void the_caller(/* ... */) {
f1_func *f1;
f2_func *f2;
// Pass the addresses of the function pointers:
set_module_functions("mod1", &f1, "mod2", &f2);
// Functions can be (in fact, always are) invoked through function pointers.
// There is no need to dereference a function pointer to call the pointed-to
// function.
f1(/* arguments */);
f2(/* arguments */);
}