Когда мы действительно пойдем за указателями на функции?особенно, как показано ниже.
Вы используете указатель на функцию, когда хотите сделать что-то более абстрактное.Например, предположим, что ваше приложение имеет графический набор инструментов с определенным количеством кнопок.Каждая кнопка соответствует экземпляру определенной структуры.
Структура кнопки может содержать указатель на функцию и контекст:
typedef struct {
void (*press_button) (void *context);
void *context;
/* Here some other stuff */
} Button;
Когда пользователь нажимает кнопку, событие выглядит примерно так:
void event_click (Button *b)
{
b->press_button(b->context);
}
Смысл в этом заключается в том, что вы можете всегда использовать одну и ту же структуру для каждой кнопки:
Button * create_button (void (*callback) (void *), void *context, /* other params */
{
Button *ret = malloc(sizeof(Button));
if (ret != NULL) {
ret->callback = callback;
ret->context = context;
/* Assign other params */
}
...
return ret;
}
Так что, когда вы строите свой набор инструментов, вы, вероятно, делаете что-то вроде
Button * toolbox[N];
toolbox[0] = create_button(function1, (void *)data, ...);
toolbox[1] = create_button(function2, (void *)something, ...);
...
toolbox[N-1] = create_button(functionN, (void *)something_else, ...);
Также, когда вы создаете некоторый указатель на функцию, всегда несите некоторую информацию о контенте (как я это сделал с полем context
структуры).Это позволяет вам избегать глобальных переменных, поэтому вы можете получить надежный и реентерабельный код!
Примечание : Этот метод великолепен, но если вы работаете с C ++, вы можете предпочесть использование объектной ориентациии заменить обратные вызовы производными от абстрактных классов.При этом вам также не нужно переносить контекст, поскольку класс сделает это за вас.
Редактировать в ответ на первый комментарий :
Текущий код, который я прохожу, относится к файлу ввода-вывода.установка переменной среды и создание символических ссылок между файлами, копирование данных из одного файла в другой и т. д. Я не понимаю, почему нам нужно вызывать эти функции во время выполнения с помощью указателей на функции.мы также можем вызывать их напрямую.
На самом деле вы можете делать то, что вам нужно, без использования указателей на функции.Если я хорошо понимаю вашу проблему, вы пытаетесь понять чужой код, который делает то, что вы перечислили с помощью указателей функций.
Лично я не использую эту функцию, если она мне не нужна, но если вы публикуете здеськакой-то дополнительный код, может быть, мы можем попытаться понять его лучше.