Подтвердить что ты не робот

Может ли статическая функция вызываться через указатель функции в C?

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

4b9b3361

Ответ 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();
}