Скажите, что у меня есть один исполняемый файл: app.exe
Я использую 2 разные сторонние DLL в этом исполняемом файле: foo.dll
bar.dll
, и Приложение должно неявно связываться с этими DLL, то есть я не могу использовать ::LoadLibrary
для их загрузки.
(Примечание: это не значит, что я не могу вызвать LoadLibrary
, но эти библиотеки DLL требуют статического связывания (библиотеки C ++ с __declspec(dllexport)
), поэтому вызов LoadLibrary
не имеет никакого смысла, потому что исполняемый загрузчик уже вызвал она.)
Эти две DLL не не имеют каких-либо зависимостей друг от друга, то есть их порядок загрузки, насколько я могу судить, не определен (а должен быть неактуальным). (Зависимости обоих типов в основном только от стандартных Windows-библиотек (kernel32, msvcrt и т. Д.)
Теперь у меня проблема с тем, что я хочу контролировать порядок загрузки этих библиотек DLL, то есть мне бы хотелось, чтобы foo.dll был всегда загружен (DLL_PROCESS_ATTACH
) до bar.dll.
Можно ли как-то сказать загрузчику Windows DLL загружать одну DLL раньше другой?
Редактировать: Чтобы проверить порядок загрузки DLL исполняемого файла, можно использовать утилиту DUMPBIN.exe
: (просто запустите командную строку Visual Studio)
Редактировать: Согласно этому ответу / этой записи в блоге , загрузчик NT последовательно проходит раздел импорта. (Это приведет к загрузке независимых DLL в том порядке, в котором они указаны в разделе импорта.)
C:\path\to\program> dumpbin /IMPORTS app.exe | grep -i \.dll
MSVCR80D.dll
KERNEL32.dll
OLEAUT32.dll
MSVCP80D.dll
foo.dll
bar.DLL
Этот вывод означает, что MSVCR80D.dll (и его зависимости [a] ) будет загружен первым, а bar.DLL будет загружен последним. Выгрузка будет происходить в обратном порядке.
То, что я еще не выяснил, это как повлиять на этот порядок загрузки ...
(Примечания)
[a]: Это, конечно, означает, что, например, Сначала будет загружен kernel32.dll, потому что msvcr80d.dll будет зависеть от kernel32.dll.
Согласно некоторым запросам, я добавляю обоснование для этого: (Но , пожалуйста , я все еще интересуюсь этим вообще. Я знаю как обойти проблему MFC. )
Microsoft MFC DLL в своей отладочной версии имеет встроенную функцию обнаружения утечки памяти. (Насколько я могу судить, это тот же механизм, который используется _CrtSetDbgFlag и соответствующими инструментами.)
DLL-библиотека отладки MFC будет выгружать всю неосвобожденную память при ее выгрузке. Теперь, если в вашем процессе есть вторая DLL, независимая от MFC, и эта вторая DLL освобождает память на DLL_PROCESS_DETACH, механизм отчетов MFC сообщит о ложных утечках памяти, если DLL MFC выгружается раньше других dll.
Если бы можно было убедиться, что отладочная MFC DLL загружается первой / выгружается последней из всех независимых DLL, то все остальные DLL уже очистились бы после себя, и MFC не сообщит о ложных утечках.