Может ли статическая функция вызываться через указатель на функцию в C? - PullRequest
28 голосов
/ 06 ноября 2011

Я считаю, что статическая функция в исходном файле не может быть вызвана напрямую из-за пределов файла. Однако, если мне как-то удастся получить указатель на эту функцию в другом файле, могу ли я затем вызвать эту функцию из этого файла. Если да, есть ли сценарий, когда мы хотели бы пойти по этому пути по сравнению с простым превращением функции в нестатическую?

Ответы [ 7 ]

31 голосов
/ 06 ноября 2011

Да, вы можете экспортировать статические функции, передавая им указатели. Это обычное средство реализации шаблона Factory в C, где вы можете скрыть реализации целого набора функций от модулей, которые их используют, и иметь FuncPtr_t GetFunction( enum whichFunctionIWant), который раздает их потребителям , Вот как много динамических связей реализаций работает.

9 голосов
/ 06 ноября 2011

Однако, если мне как-то удастся вставить указатель на эту функцию в другой файл, могу ли я затем вызвать эту функцию из этого файла.

Да, это вполне возможно.Функция не видна компоновщику, но она есть в исполняемом файле.Вы всегда можете перейти к его адресу.

Я не уверен насчет сценариев, хотя.Может быть, вы хотите, чтобы другие вызывали вашу функцию только после , которую они вызывали для какой-то другой функции (конечно, не статичной).Таким образом, у вас есть получение этого, и тогда они могут назвать его.

4 голосов
/ 06 ноября 2011

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

3 голосов
/ 06 ноября 2011

Да, вы можете. Если вам нужно вызвать функцию, которая ожидает указатель на функцию в качестве обратного вызова, вы можете использовать static, чтобы символ функции не загрязнял глобальное пространство имен и не вызывал конфликты компоновщика. Наиболее часто используемый пример - это qsort:

struct Data { ... };

static int compareData(const void* a, const void* b) { /* cast to Data and compare */ }

...
qsort(array, count, sizeof(Data), &compareData);
3 голосов
/ 06 ноября 2011

Да, нестатическая функция в вашем файле может вернуть указатель на статическую функцию в любое место.

2 голосов
/ 06 ноября 2011

Часто полезно определить небольшую статическую функцию как рабочую функцию для какой-то другой. Посмотрите на стандарт qsort в качестве примера: он ожидает функцию сравнения, и очень часто лучше, чтобы эта функция сравнения была статической (например, потому что она бесполезна в другом месте, и потому что qsort хочет, чтобы она имела некоторую неподписанную сигнатуру). ).

0 голосов
/ 06 ноября 2011

Да, вы можете, вы всегда можете попробовать сами и узнать:

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();
}
...