C: Как я могу использовать один массив указателей на функции для функций с переменным числом параметров? - PullRequest
11 голосов
/ 06 октября 2011

Вопрос в значительной степени говорит сам за себя.

Я не уверен, как это сделать, и не сталкивался ни с чем, что работает.

Вот несколько примеров функций:

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

и,

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

До сих пор я пытался использовать typedef с обоими, но я не могу понять, как заставить что-то указывать на один из типов:

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

????? func_table[2] = {add, mean};

Ответы [ 4 ]

30 голосов
/ 06 октября 2011

Вам необходимо выбрать тип указателя на функцию, который будет использоваться в качестве «универсального указателя на функцию», использовать этот тип для определения массива и использовать явное приведение типов.Приведение одного типа указателя на функцию к другому и затем обратно гарантирует сохранение значения.

Другими словами:

typedef int (*generic_fp)(void);

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

Затем, чтобы вызвать add, вам необходимо привести его обратновправо введите:

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

Вы можете определить некоторые макросы, если посчитаете их более приемлемыми:

#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);
3 голосов
/ 06 октября 2011

Вы можете использовать шаблон фасада , например:

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 };

Хотя код некрасив, он делает свою работу. Вы должны добавить некоторую логику проверки в оболочках.

1 голос
/ 06 октября 2011
int (*func[])() = { add, mean };
0 голосов
/ 06 октября 2011

Эти два типа функций несовместимы.Строго говоря, они могут быть реализованы с использованием совершенно другой передачи аргументов.Например, реализация может выбрать, чтобы все функции с максимум 3 параметрами получали их через регистры, а все другие функции получали их через стек.

Однако вы можете определить обе функции с помощью varargs параметры, чтобы они следовали той же схеме передачи параметров.

Как вы намеревались в любом случае вызывать эти функции, не зная, сколько параметров они ожидают?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...