Я считаю, что статическая функция в исходном файле не может быть вызвана непосредственно из-за пределов файла. Однако, если мне удастся получить указатель на эту функцию в другой файл, могу ли я затем вызвать эту функцию из этого файла. Если да, есть ли какой-либо сценарий, когда мы хотели бы использовать этот маршрут по сравнению с простое выполнение функции нестатической?
Может ли статическая функция вызываться через указатель функции в C?
Ответ 1
Да, вы можете экспортировать статические функции, передавая им указатели. Это распространенное средство реализации Factory pattern на C, где вы можете скрыть реализации целого ряда функций из модулей, которые использовать их и иметь FuncPtr_t GetFunction( enum whichFunctionIWant)
, который передает их потребителям. Это работает динамическая компоновка.
Ответ 2
Однако, если мне как-то удастся получить указатель на эту функцию в другой файл, могу ли я затем вызвать эту функцию из этого файла.
Да, это вполне возможно. Функция не видна компоновщику, но она есть в исполняемом файле. Вы всегда можете перейти к его адресу.
Я не уверен в сценариях. Возможно, вы хотите, чтобы другие вызывали вашу функцию только после того, как они вызвали какую-то другую функцию (нестатическую, конечно). Таким образом, вы получите их, и тогда они могут это назвать.
Ответ 3
Как уже упоминалось, вы можете это сделать. Примером того, почему вы, возможно, захотите, является какой-то "драйвер". Вы можете передать структуру, содержащую функции open, close, read и write, без необходимости публиковать доступные функции.
Ответ 4
Да, нестатическая функция в вашем файле может возвращать указатель на статическую функцию в любом месте.
Ответ 5
Да, вы можете. Если вам нужно вызвать функцию, которая ожидает указатель на функцию в качестве обратного вызова, вы можете использовать static, чтобы символ функции не загрязнял глобальное пространство имен и не вызывал конфликты компоновщика. Наиболее часто используемый пример, вероятно, qsort:
struct Data { ... };
static int compareData(const void* a, const void* b) { /* cast to Data and compare */ }
...
qsort(array, count, sizeof(Data), &compareData);
Ответ 6
Часто бывает полезно определить небольшую статическую функцию в качестве рабочей функции для какой-либо другой. Посмотрите на стандартный qsort
для примера: он ожидает функцию сравнения, и очень часто лучше сделать эту функцию сравнения статичной (например, потому что она не полезна в другом месте, а потому, что qsort
хочет, чтобы она имела некоторую нечеткую подпись).
Ответ 7
Да, вы можете, вы всегда можете попробовать это для себя и узнать:
file1.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;
}
file2.c
void call_hello(void (*fptr)(void))
{
fptr();
}