Можете ли вы запустить функцию по инициализации в c? - PullRequest
5 голосов
/ 21 июня 2010

Есть ли механизм или прием для запуска функции при загрузке программы?

Чего я пытаюсь достичь ...

void foo(void)
{
}

register_function(foo);

, но очевидно, что register_function не запустится.

, поэтому хитрость в C ++ заключается в использовании инициализации дляфункция запускается

что-то вроде

int throwaway = register_function(foo);

, но это не работает в C. Поэтому я ищу способ обойти это, используя стандартный C (ничего не зависит от платформы / компилятора)

Ответы [ 3 ]

14 голосов
/ 21 июня 2010

Если вы используете GCC, вы можете сделать это с помощью атрибута функции constructor, например:

#include <stdio.h>

void foo() __attribute__((constructor));

void foo() {
    printf("Hello, world!\n");
}

int main() { return 0; }

Однако в C нет переносимого способа сделать это.

Если вы не возражаете возиться с вашей системой сборки, у вас есть больше возможностей.Например, вы можете:

#define CONSTRUCTOR_METHOD(methodname) /* null definition */

CONSTRUCTOR_METHOD(foo)

Теперь написать сценарий сборки для поиска экземпляров CONSTRUCTOR_METHOD и вставить последовательность вызовов к ним в функцию в сгенерированном файле .c.Вызвать сгенерированную функцию в начале main().

3 голосов
/ 21 июня 2010

Стандарт С не поддерживает такую ​​операцию. Если вы не хотите использовать для этого специальные функции компилятора, то вашей следующей лучшей идеей может быть создание глобального статического флага, инициализированного как false Затем, когда кто-нибудь вызывает одну из ваших операций, требующих регистрации указателя функции, вы проверяете этот флаг. Если это ложно, вы регистрируете функцию, а затем установите флаг в true. Последующие звонки не должны будут выполнять регистрацию. Это похоже на ленивый экземпляр, используемый в шаблоне проектирования OO Singleton.

0 голосов
/ 21 июня 2010

Стандартного способа сделать это не существует, хотя gcc предоставляет атрибут constructor для функций.

Обычный способ обеспечить некоторую предварительную настройку (кроме простой инициализации переменной для компиляции).значение времени), чтобы убедиться, что все функции, требующие предварительной настройки.Другими словами, что-то вроде:

static int initialized = 0;
static int x;

int returnX (void) {
    if (!initialized) {
        x = complicatedFunction();
        initialized = 1;
    }
    return x;
}

Лучше всего это сделать в отдельной библиотеке, поскольку она изолирует вас от реализации.

...