Passing pointer to function to function and assign it in C - c

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__ in extfunc will execute fX_modY or fX_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 */);
}

Assuming the functions take the same number and type of arguments¹, you can declare an array of function pointers and assign to each pointer the address of a function:
void (*foo[SIZE]) (void) = { &f1_mod, &f2_mod,
&f3_mod, &f4_mod };
Pass the array to the function as:
__thefunctioniwouldlike (foo);
The function declaration can be written as:
void __thefunctioniwouldlike (void (*foo[]) (void), ...);
Then assign it to __f1__ as:
__f1__ = foo[0];
In a similar vein, instead of passing the char * as separate arguments, you can declare an array of char *s:
char *ret[SIZE] = { "mod1", "mod2", "mod3", "mod4" };
Pass it to the function as:
__thefunctioniwouldlike (foo, ret);
The function declaration can be written as:
void __thefunctioniwouldlike (void (*foo[]) (void), char *ret[]);
Compare the string pointed to by the pointer as:
strcmp (ret[0], "foo1");
Execute the function pointed to by the zeroth member of the array as:
(*foo[0])();
Or simply:
foo[0]();
Sample code:
/* Note: I am not very fond of `typedef`s,
* but they could help with readability here.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void f1_mod (void) { }
static void f2_mod (void) { }
static void f3_mod (void) { }
static void f4_mod (void) { }
static void func (void (*foo[])(void), char *ret[], void (**tmp)(void)) {
if (!strcmp (ret[0], "mod1")) {
*tmp = foo[0];
}
}
int main (void)
{
void (*foo[]) (void) = { &f1_mod, &f2_mod, &f3_mod, &f4_mod };
void (*tmp) (void) = 0;
char *ret[] = { "mod1", "mod2", "mod3", "mod4" };
func (foo, ret, &tmp);
return EXIT_SUCCESS;
}
[1] — If that's not true, you can still follow the same approach, and call internal functions inside with the relevant arguments.
For example:
static void f1_mod1 (void)
{
f1_mod1_internal (...);
}

Related

How can I register a simple callback function and pass arguments to that function?

What I would like to do is :
a simple function "register_function" allowing a user to indicate a callback function to call (that this user has implemented)
when calling that function with "call_callback", to be able to pass arguments like a buffer for example
Here is my code:
static void (*callback)(int *buffer, int size) = NULL;
void register_callback(void (*ptr)())
{
(*callback) = ptr;
}
void call_callback(int *buffer, int size)
{
(*callback)(buffer, size);
}
The problem is that I have a compile-time error in the register_callback declaration.
In register_callback() the assignment is just:
void register_callback(void (*ptr)( int *buffer, int size ))
{
callback = ptr;
}
Please note that I also added the parameter declarations to the definition of ptr so the compiler can check for the correct function pointer type passed (assuming you have an identical prototype)

How to create a function that returns another function, encompassing a given argument implicitly in C?

I want to have a function that returns a function that is called without an argument, even though the original function must be called with an argument. The argument is passed to the first function and will be implicitly used each time a call to the returned function is made.
I am aware of function pointers in C but I don't know if they can be used in such a way. I know how to do this in python as shown in the following sample code :
def foo(some_argument):
print(some_argument)
def register_callback(function, argument):
def new_function():
function(argument)
return new_function
bar = register_callback(foo,"bar")
bar()
From what I read, this way is not possible in C because we can't nest function definitions. Is this possible and if so what would be the proper way to do it?
About all you can do in C is create a record (a struct) containing both the function pointer and the argument to pass and then use that record as the “thing” that is called, with the assistance of a wrapper function that does the actual calling.
#include <stdio.h>
typedef int SomeType; // Sample type for demonstration.
// Define a record to hold a function pointer and the argument we want to pass.
typedef struct
{
void (*Function)(SomeType); // Function to call.
SomeType Argument; // Argument to pass.
} Closure;
// Define some sample functions.
static void A(SomeType x) { printf("Called %s(%d).\n", __func__, x); }
static void B(SomeType x) { printf("Called %s(%d).\n", __func__, x); }
// Define a function that returns a closure.
static Closure foo(int Which, SomeType x)
{
return (Closure) { .Function = Which & 1 ? B : A, .Argument = x };
}
// Define a function to call a closure.
static void Call(Closure C) { C.Function(C.Argument); }
int main(void)
{
Closure a = foo(0, 34);
Closure b = foo(1, 79);
Call(a);
Call(b);
}
Output:
Called A(34).
Called B(79).

Functions pointers

Hey guys I have a question: How can i call a function from an enum structure with pointers?
For example I have this structure:
typedef enum struct_e
{
FUNCTION_ONE,
FUNCTION_TWO,
FUNCTION_THREE,
FUNCTION_FOUR,
} sctruct_t;
And I have a function that receives one of these variables and the parameters of the function (for example an int)
void call_functions(struct_t action, int exemple) {...}
// -> call like this call_functions(FUNCTION_ONE, 45);
And in that function I have to call one of the functions like this one:
void function_one(int a)
{
printf("You have %d years old", a);
}
Assuming each of the functions to call has type void (*)(int), you can create an array of function pointers, using the enum values as the array index:
typedef void (*call_func_type)(int);
call_func_type func_list[] = {
[FUNCTION_ONE] = function_one,
[FUNCTION_TWO] = function_two,
[FUNCTION_THREE] = function_three,
[FUNCTION_FOUR] = function_four
}
Then call_functions would just index into that array:
void call_functions(struct_t action, int example)
{
func_list[action](example);
}
I usually find that the first step when dealing with a function pointer is to use a typedef to make the syntax more readable. Then, such pointers can be used much like any other data type.
// declares function_ptr as a new type, pointer to function taking an integer parameter and returning void
typedef void (*function_ptr)(int);
// define function pointer p and initialize to point at function one
function_ptr p = function_one;
// call function_one passing 7 as a parameter
(*p)(7);
In this case, assuming that all of the functions take an integer as a parameter, we can use a table of pointers to represent all the functions you'd want to call:
function_ptr table[]=
{
function_one,
function_two,
function_three,
function_four,
};
At this point it's fairly easy to call any number of functions using this method.
void call_functions(struct_t action, int exemple)
{
if( action >= FUNCTION_ONE && action <= FUNCTION_FOUR )
{
(table[action])(exemple);
}
else
{
printf("Unrecognized function %i. Check that function table is up to date\n", (int)action);
}
}

How to call different functions on different int values in c

In an interview I was asked to write an efficient program such that for each integer value given, a function is called.
For example: if user enters 1 then function one will get executed if user enters 5 then function five gets executed and so on..
I was not able to come up with an efficient idea, like we can't use an if statement for checking the value entered and then executing the corresponding functions.
Is there any way we can do this in an efficient manner?
One of the option would be using function pointers, as below.
Declares a type of a void function
typedef void (*fp)();
define your functions
void func1()
{}
.
.
.
void func10()
{}
declare array of function pointers like below
fp function_pointers[10]; //declares the array
Initialize the function pointers like below
function_pointers[0] = func1()
.
.
function_pointers[9] = func10()
Call function using function pointers like below
for (int i=0;i<10;i++)
function_pointers[i]();
Use function pointers.
Simple example:
#include <stdio.h>
//pointer to a void function declaration
typedef void(*someFunc)();
void f1() {
printf("f1 function call\n");
}
void f2() {
printf("f2 function call\n");
}
void f3() {
printf("f3 function call\n");
}
//array of function pointers
const someFunc funcTable[] = {
f1,
f2,
f3
};
int main() {
uint number = 0;
printf("Enter 0, 1 or 2\n");
scanf("%u",&number);
if(number < 3) {
funcTable[number]();
}
}

Function Returning Itself

Is it possible to declare some function type func_t which returns that type, func_t?
In other words, is it possible for a function to return itself?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
Or would I have to use void * and typecasting?
No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.
Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.
A possible solution with structs:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.
You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
Output:
Called a function
Called a function
Called a function
In other words, is it possible for a function to return itself?
It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.
The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.
Check my answer for details.
Assume the function definition
T f(void)
{
return &f;
}
f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).
If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like
T f(void)
{
return (T) &f;
}
but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.
C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.
what about something like this:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
printf("%s\n", __func__);
return stop(a);
}
void *stop (int *a) {
printf("%s\n", __func__);
return start(a);
}
int main (void) {
int a = 10;
fptr f = start;
f(&a);
return 0;
}
It is not possible for a function to return itself by value. However it is possible itself to return by a pointer.
C allows to define function types that take undefined number of parameters and those those types are compatible with function types that take defined parameters.
For example:
typedef void fun_t();
void foo(int);
fun_t *fun = foo; // types are fine
Therefore the following function would work.
void fun(void (**ptr)()) {
*ptr = &fun;
}
And below you can find the exemplary usage:
#include <stdio.h>
void fun(void (**ptr)()) {
puts("fun() called");
*ptr = &fun;
}
int main() {
void (*fp)();
fun(&fp); /* call fun directly */
fp(&fp); /* call fun indirectly */
return 0;
}
The code compiles in pedantic mode with no warnings for C89 standard.
It produces the expected output:
fun() called
fun() called
There's a way, you just try this:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().

Resources