У меня есть вопрос относительно динамической инициализации (т.е. конструкторов перед основным) и порядка ссылок DLL - как для Windows, так и для POSIX.
Чтобы было легче говорить, я дам определение паре терминов:
Библиотеки времени загрузки: библиотеки, которые были "связаны" во время компиляции таким образом, что когда система загружает мое приложение, они загружаются автоматически. (т. е. помещенные в команду target_link_libraries CMake).
Библиотеки времени выполнения: библиотеки, которые я загружаю вручную с помощью dlopen или эквивалентов. Для целей этого обсуждения я скажу, что я когда-либо вручную загружал библиотеки, используя dlopen в основном, так что это должно упростить ситуацию.
Динамическая инициализация. Если вы не знакомы с определением этого в спецификации C++, не пытайтесь ответить на этот вопрос.
Итак, допустим, у меня есть приложение (MyAwesomeApp), и оно ссылается на динамическую библиотеку (MyLib1), которая, в свою очередь, ссылается на другую библиотеку (MyLib2). Итак, дерево зависимостей:
MyAwesomeApp -> MyLib1 -> MyLib2
Для этого примера предположим, что MyLib1 и MyLib2 являются библиотеками времени загрузки.
Каков порядок инициализации вышеизложенного? Очевидно, что вся статическая инициализация, включая связывание экспортируемых/импортируемых функций (только для Windows) будет происходить первой... Но что происходит с динамической инициализацией? Я ожидаю общий порядок:
ВСЕ связывание символов импорта/экспорта
ВСЕ статические инициализации
ВСЕ динамические инициализации MyLib2
ВСЕ динамические инициализации MyLib1
ВСЕ динамические инициализации MyAwesomeApp
Функция main() MyAwesomeApp
Но я не могу найти ничего в спецификациях, которые требуют этого. Я ДЕЙСТВИТЕЛЬНО видел что-то с эльфом, намекающее на это, но мне нужно найти гарантии в спецификациях, чтобы сделать то, что я пытаюсь сделать.
Просто чтобы убедиться, что мои мысли ясны, я ожидаю, что загрузка библиотеки работает очень похоже на «импорт в Python» в том смысле, что, если она еще не загружена, она будет загружена полностью (включая любую инициализацию), прежде чем я это сделаю что-нибудь... и если оно было загружено, то я просто дам на него ссылку.
Чтобы привести более сложный пример, чтобы убедиться, что нет другого определения моего первого примера, которое дает другой ответ:
MyAwesomeApp зависит от MyLib1 и MyLib2 MyLib1 зависит от MyLib2
Я ожидаю следующую инициализацию:
ВСЕ связывание символов импорта/экспорта
ВСЕ статические инициализации
ВСЕ динамические инициализации MyLib2
ВСЕ динамические инициализации MyLib1
ВСЕ динамические инициализации MyAwesomeApp
Функция main() MyAwesomeApp
Я был бы рад любой помощи, указывающей на спецификации, которые говорят, что это так. Или, если это неправильно, любая спецификация говорит о том, что НА САМОМ ДЕЛЕ происходит!
Заранее спасибо!
-Кристофер