Существует ли механизм или прием для выполнения функции когда загрузки программы?
Чего я пытаюсь достигнуть...
void foo(void)
{
}
register_function(foo);
но очевидно register_function не будет работать.
таким образом, прием в C++ должен использовать инициализацию для создания функции выполненной
что-то как
int throwaway = register_function(foo);
но это не работает в C. Таким образом, я ищу путь вокруг этого стандарта использования C (ничто платформа / конкретный компилятор)
Если вы используете GCC, вы можете сделать это с помощью атрибута функции конструктора
, например:
#include <stdio.h>
void foo() __attribute__((constructor));
void foo() {
printf("Hello, world!\n");
}
int main() { return 0; }
Однако в Си нет переносимого способа сделать это.
Однако если вы не против возиться с вашей системой сборки, у вас есть больше возможностей. Например, вы можете:
#define CONSTRUCTOR_METHOD(methodname) /* null definition */
CONSTRUCTOR_METHOD(foo)
Теперь напишите сценарий сборки для поиска экземпляров CONSTRUCTOR_METHOD и вставьте последовательность вызовов этих экземпляров в функцию в сгенерированном .c файле. Вызовите сгенерированную функцию в начале main()
.
Стандартного способа сделать это не существует, хотя gcc предоставляет атрибут конструктор
для функций.
Обычный способ обеспечения выполнения некоторой предварительной настройки (кроме простой инициализации переменной значением времени компиляции) - убедиться, что все функции, требующие этой предварительной настройки.Другими словами, что-то вроде:
static int initialized = 0;
static int x;
int returnX (void) {
if (!initialized) {
x = complicatedFunction();
initialized = 1;
}
return x;
}
Это лучше всего делать в отдельной библиотеке, поскольку это изолирует вас от реализации.
Стандарт C не поддерживает такую операцию. Если вы не хотите использовать для этого специфические возможности компилятора, то лучшим вариантом будет создание глобального статического флага, который инициализируется в false. Тогда всякий раз, когда кто-то вызывает одну из ваших операций, требующих регистрации указателя функции, вы проверяете этот флаг. Если он равен false, вы регистрируете функцию, а затем устанавливаете флаг в true. Последующие вызовы не должны будут выполнять регистрацию. Это похоже на ленивое инстанцирование, используемое в шаблоне проектирования OO Singleton.