Я использую сторонний API, который переопределяет функции управления памятью, которые есть в библиотеках C Runtime. Для того, чтобы все работало правильно, я должен позвонить, чтобы инициализировать API, прежде чем произойдет какое-либо выделение памяти.
В проекте, над которым я работаю, используется статический объект Factory, который динамически инициализируется перед выполнением любого кода в основном файле.
Как я могу гарантировать, что API будет инициализирован до статического объекта Factory?
Стандартная библиотека C ++ сталкивается с той же проблемой: она должна гарантировать, что cin
, cout
и т. д. инициализируются до того, как какой-либо код, включая конструкторы для статических объектов, использует их. Трюк, который был изобретен для решения этой ситуации, также может решить ваш. В заголовочном файле, который включается первый в каждой единице перевода (ну, в каждой единице перевода, которая имеет статические объекты с динамическими инициализаторами):
class init_library {
public:
init_library() { if (counter++ == 0) initilaize_the_library(); }
private:
static int counter;
};
static init_library i_library;
и в одной единице перевода вы должны дать определение init_library::counter
,
Это поместит статический объект типа init_library
в каждой единице перевода, которая тянет в заголовке. Произойдет его инициализация до любая другая инициализация в том же модуле перевода (потому что пришла его директива #include первый — не забывайте об этом!), и в первый раз, когда один из этих объектов будет инициализирован, он вызовет код для инициализации библиотеки. (Обратите внимание, что этот код не является потокобезопасным; сделать его потокобезопасным просто)
Это известно как «изящный контр-трюк».
Вам следует переместить инициализацию статических объектов фабрики в статическую функцию и вызвать эту функцию после инициализации сторонней библиотеки lib в качестве первой вещи в main.