Можно ли вызвать статическую функцию через указатель на функцию в языке Си?
Я считаю, что статическая функция в исходном файле не может быть вызвана непосредственно из-за пределов файла. Однако, если мне каким-то образом удастся получить указатель на эту функцию в другой файл, я могу вызвать эту функцию из этого файла. Если да, то есть ли какой-либо сценарий, когда мы хотели бы пойти этим путем по сравнению с простым созданием функции нестатической ?
7 ответов:
Да, вы можете экспортировать статические функции, выдавая на них указатели. Это распространенное средство реализации фабричного шаблона В C, где можно скрыть реализации целого набора функций от модулей, которые их используют, и иметь
FuncPtr_t GetFunction( enum whichFunctionIWant)
, который раздает их потребителям. Именно так работает множество реализацийдинамического связывания .
Однако, если мне каким-то образом удастся получить указатель на эту функцию в другой файл, могу ли я тогда вызвать эту функцию из этого файла.
Да, это вполне возможно. Функция не видна компоновщику, но она есть в исполняемом файле. Вы всегда можете перейти по его адресу.
Хотя я не уверен в сценариях. Может быть, вы хотите, чтобы другие вызывали только вашу функцию после того, как они вызвали какую-то другую функцию (нестатическую, конечно). Так что они у вас есть получить его, а затем они могут вызвать его.
Как уже упоминалось, вы можете это сделать. Пример того, почему вы можете захотеть, - это для какого-то"водителя". Вы можете передать обратно структуру, содержащую функции open, close, read и write, не делая их общедоступными.
Да, нестатическая функция в вашем файле может возвращать указатель на статическую функцию в любое место.
Да, можешь. Если необходимо вызвать функцию, которая ожидает указатель на функцию в качестве обратного вызова, можно использовать статический метод, чтобы символ функции не загрязнял глобальное пространство имен и не вызывал конфликтов компоновщика. Наиболее часто используемый пример, вероятно, qsort:
struct Data { ... }; static int compareData(const void* a, const void* b) { /* cast to Data and compare */ } ... qsort(array, count, sizeof(Data), &compareData);
Часто бывает полезно определить небольшую статическую функцию как рабочую функцию для какой-то другой. Посмотрите на стандарт
qsort
для примера: он ожидает функцию сравнения, и очень часто лучше сделать эту функцию сравнения статической (например, потому, что она не полезна в другом месте, и потому, чтоqsort
хочет, чтобы она имела некоторую непреттированную подпись).
Да, вы можете, вы всегда можете попробовать это для себя и узнать:
файл 1.c
#include <stdio.h> void call_hello(void (*fptr)(void)); static void hello(void) { puts("hello"); } int main(void) { void (*fptr)(void) = hello; call_hello(fptr); return 0; }
файл 2.c
void call_hello(void (*fptr)(void)) { fptr(); }