У меня есть проект C / C ++ с большим количеством модулей, которые предназначены для добавления и удаления между установками (они похожи на «плагины»). Я хотел значительно упростить инициализацию модуля, используя технику, аналогичную ядру Linux - всякий раз, когда ядро связано с каким-либо модулем .c, макрос module_init () в файле .c «регистрирует» модуль на каком-то глобальном сайте, поэтому его можно callback'd позже, чтобы быть должным образом инициализирован.
Вопрос: Как мне это сделать без каких-либо неприятных трюков с ссылками?
Я попробовал один подход, примерно следующий:
во всех модулях есть макрос module_init (initfunc), который расширяется в нечто вроде
struct _initializer_ {
_initializer_() {
register_init_function(initfunc);
}
} _init_instance_;
Функция register_init_function хранит указатель initfunc в виде списка, поэтому его можно инициализировать основной программой позже.
Проблема здесь в том, что глобальные переменные C обнуляются перед использованием в неконтролируемом порядке, поэтому случается, что некоторые модули правильно регистрируются, а регистрация других стирается, когда основной модуль «инициализируется» после них. Я также попробовал некоторые трюки со статическим классом и порядком инициализации глобальной переменной, но либо полностью неправильно понял описание, либо они не работают.
Вопрос: существует ли какой-либо метод для обеспечения порядка инициализации или какой-либо другой метод для такой инициализации модуля?
[РЕДАКТИРОВАТЬ] прямое объяснение:
- main.c имеет глобальную переменную Y
- main.h описывает эту глобальную переменную или какой-то возможный способ ее изменения (функция X ())
- module.c вызывает функцию X () (или любую другую Y-модифицирующую вещь), чтобы как можно скорее сохранить что-либо в переменной Y, без ссылки на main.c .
- main.c может после этого увидеть, что кто-то вызвал X () и сохранил материал в Y.
Пример назначения: gcc main.c modules / common / .c modules / some_specific_purpose / .c