Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: How can I use a single function pointer array for functions with variable parameter counts?

The question pretty much says it all.

I'm not sure how to do this and haven't come anywhere near anything that works.

Here's some example functions:

add(int x, int y) {
  return x+y;
}

and,

mean(int x1, int y1, int x2, int y2) {
  return (x1 + y1 + x2 + y2) / 4;
}

So far I've tried using typedef with both, but I can't figure how to make something point to one of either type:

typedef int (*mathfunc2)(int x, int y);
typedef int (*mathfunc4)(int x1, int y1, int x2, int y2);

????? func_table[2] = {add, mean};
like image 839
vaughanj Avatar asked Oct 06 '11 06:10

vaughanj


2 Answers

You need to pick a function pointer type to use as a "generic function pointer", use that type to define your array, and use explicit casts. Casting one function pointer type to another and then back again is guaranteed to preserve the value.

In other words:

typedef int (*generic_fp)(void);

generic_fp func_table[2] = { (generic_fp)add, (generic_fp)mean };

Then to call add, you need to cast it back to the right type:

result = ((mathfunc2)func_table[0])(x, y);

You can define some macros if you find it more palatable:

#define FUNC_2(f, p1, p2) ((mathfunc2)(f))(p1, p2)
#define FUNC_4(f, p1, p2, p3, p4) ((mathfunc4)(f))(p1, p2, p3, p4)

result = FUNC_2(func_table[0], x, y);
like image 111
caf Avatar answered Oct 10 '22 15:10

caf


You could use the Facade Pattern like this:

int add(int x, int y);
int mean(int x1, int y1, int x2, int y2);

typedef int (*operation_fp)(int argc, int* argv);

int add_wrapper(int argc, int* argv) { return add(argv[0], argv[1]); }
int mean_wrapper(int argc, int* argv) { return mean(argv[0], argv[1], argv[2], argv[3]); }

operation_fp func_table[2] = { add_wrapper, mean_wrapper };

Although the code is ugly, it does the job. You should add some validation logic in wrappers.

like image 21
npclaudiu Avatar answered Oct 10 '22 17:10

npclaudiu