AddDllDirectory мешает последующему LoadLibraryExW - PullRequest
0 голосов
/ 24 февраля 2020

В нашем приложении у нас есть специальная структура для пути поиска DLL. Из-за обновления сторонней библиотеки разрешение dll теперь не работает. Попытки исправить путь поиска с помощью AddDllDirectory привели к неожиданным проблемам.

MyApp.exe является приложением C++/MFC и использует Managed#1.dll, который, в свою очередь, вызывает собственную dll. Кроме того, ему нужно MyNativeDll.dll, которое установлено в другой папке:

Folder structure:
Program Files\MyApp\MyApp.exe
                   \Managed#1.dll                  
                   \x86\Native#1.dll
Program Files\MyDll\MyNativeDll.dll
                   \Managed#2.dll
                   \x86\Native#2.dll

Первоначальная проблема, с которой мы столкнулись, заключалась в том, что Native#2.dll не был найден (этот dll был добавлен в обновлении третьей стороны). библиотека в Managed#2.dll). Поэтому я добавил следующее к DllMain из MyNativeDll:

MyNativeDll.dll::DllMain
{
    [...]
    SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
    AddDllDirectory("[...]Program Files\MyDll\x86");
}

После этого Native#2.dll загружается, как и ожидалось.

Но : сейчас когда MyApp.exe загружает Managed#1.dll, этот вызов не выполняется, так как Managed#1.dll не может загрузить Native#1.dll. Проблема с вызовом c теперь такова (следующее в какой-то сторонней библиотеке):

Managed#1.dll::Foo()
{
    LoadLibraryExW("Native#1.dll", NULL, 0);  //<-- This searches in the wrong path
}

Согласно документации , AddDllDirectory должен добавить только какой-то каталог в поиск дорожка.

Как AddDllDirectory может вызвать сбой при последнем вызове LoadLibraryExW?

1 Ответ

0 голосов
/ 26 февраля 2020

Оказалось, что проблемным вызовом c был не AddDllDirectory(), а предыдущий SetDefaultDllDirectories().

В документации указано несколько флагов (LOAD_LIBRARY_SEARCH_APPLICATION_DIR , LOAD_LIBRARY_SEARCH_SYSTEM32, LOAD_LIBRARY_SEARCH_USER_DIRS) и заявляет, что LOAD_LIBRARY_SEARCH_DEFAULT_DIRS является комбинацией этих трех.

В любом случае, существует другая опция LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, которая не упомянута в этом списке. Таким образом, вызов

SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);

фактически удалил LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR из пути поиска. Замена вышеупомянутого на

SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);

устранила проблему.

...