I'm trying to pass an array of function pointers to a function by a void pointer. I cannot figure how to access the elements of the array inside the function they are passed to.
Example 1 - Pass regular array via void pointer:
#include <stdio.h>
void function(void* ptr)
{
int* arr = ptr;
for(int i = 0; i < 5; ++i)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr_nums[5] = { 1, 2, 3, 4, 5 };
function((void*)arr_nums);
return 0;
}
Output:
1 2 3 4 5
Example 2 - Pass functions via void pointer:
#include <stdio.h>
int add(int a, int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
int mult(int a, int b)
{
return (a * b);
}
int divide(int a, int b)
{
return (a / b);
}
int function(void *ptr)
{
return ((int(*)(int, int))ptr)(4, 2);
}
int main()
{
printf("%d\n, function((void*)add));
printf("%d\n, function((void*)sub));
printf("%d\n, function((void*)mult));
printf("%d\n, function((void*)divide));
return 0;
}
Output:
6
2
8
2
Example 3 - Change add, sub, mult and divide to be a function pointer array:
...
int main()
{
int (* fp_arr[4])(int, int) = { add, sub, mult, divide };
printf("%d\n", function((void*)fp_arr[0]));
printf("%d\n", function((void*)fp_arr[1]));
printf("%d\n", function((void*)fp_arr[2]));
printf("%d\n", function((void*)fp_arr[3]));
return 0;
}
Output:
6
2
8
2
Problem - Trying to send the whole function pointer array and access the elements inside function:
...
int function(void *ptr)
{
return ((int(*)(int, int))ptr)(4, 2); <--- How to say something like ptr[2], would call mult
}
int main()
{
int (* fp_arr[4])(int, int) = { add, sub, mult, divide };
printf("%d\n", function((void*)fp_arr));
return 0;
}
Edit: I left out some details as I was trying to only outline the problem itself, the function I am passing the function pointer array to is from a graphics library and therefore I cannot change the parameter type from void* to something else. Although I do agree with making a typedef'd alias. The library itself is LVGL, but essentially I add a callback function to an object that is triggered on an event with some user data.
i.e - lv_obj_add_event_cb(obj, callback_fn, my_event_trigger, user_data);
Where user data would be my function pointer array.
Later when "my_event_trigger" happens on "obj" callback_fn will be called.
Inside the callback function I can access the user data through a function that returns a void pointer like so:
void callback_fn(lv_event_t* e)
{
lv_event_get_user_data(e); // would return a pointer to my data
// what I want would be something like
fp_arr[state]; // where it would call a different function depending on the state of the GUI
}
Therefore unfortunately I cannot change the type from a void*, but I still don't know how to reference it in such a way that I can access the elements.
There is a missing *
in the cast in your example, ptr
is a pointer to an array of function pointers:
int function(void *ptr)
{
return ((int(**)(int, int))ptr)[2](4, 2);
}
int main()
{
int (*fp_arr[4])(int, int) = { add, sub, mult, divide };
printf("%d\n", function(fp_arr));
return 0;
}
Note however that function pointers cannot be portably cast as data pointers and vice versa, so function((void *)fp_arr[0])
and function((void*)add)
are not portable, as well as ((int(*)(int, int))ptr)(4, 2)
in examples 2 and 3.