Задержка загрузки DLL в windows: можно ли динамически выбирать, какое имя DLL искать? (C ++) - PullRequest
1 голос
/ 27 марта 2020

У меня есть библиотека, которая вызывает функции из foo.dll.

В моих настройках MSVS я задерживаю загрузку foo.dll и вручную проверяю его существование, прежде чем пытаться вызвать его функции (так что если он не не существует на машине, моя библиотека не взломает sh).

Если проверка существования DLL успешно завершена, и я вызываю ее функции, DLL автоматически загружается при задержке загрузки windows помощник и все работает хорошо.

Однако на 50% компьютеров моего пользователя foo.dll был переименован в bar.dll. Даже если я вызываю LoadLibrary ("path \ bar.dll"), и она успешно выполняется, моя библиотека все равно падает, потому что помощник по отложенной загрузке все еще пытается загрузить foo.dll при вызове одной из функций.

Я использовал шестнадцатеричный редактор для просмотра содержимого моей библиотеки, и в одном месте «foo.dll» явно назван. Если я переименую эту запись в "bar.dll" с помощью шестнадцатеричного редактора, моя библиотека будет работать без ошибок, когда bar.dll - это имя DLL на компьютере пользователя (и происходит сбой, когда foo.dll - это имя). Так что, похоже, проблема в том, что помощник с задержкой загрузки пытается загрузить DLL с явно заданным именем внутри моей библиотеки.

Как я могу сказать помощнику по отложенной загрузке, что рассматриваемая DLL имеет имя, которое не соответствует явное имя файла в моей скомпилированной библиотеке?

1 Ответ

2 голосов
/ 27 марта 2020

Чтобы указать помощнику отложенной загрузки использовать другую DLL, чем та, к которой он привязан, вы можете использовать ловушку сбоя отложенной загрузки . По MSDN:

Поддержка компоновщика DLL-библиотек с задержкой: обработка ошибок и уведомление

Если вашему коду необходимо восстановить или предоставить альтернативную библиотеку и / или в случае сбоя может быть предоставлена ​​функция поддержки, которая может поставить или исправить ситуацию. Подпрограмма ловушки должна возвращать подходящее значение, чтобы обработка могла продолжаться (HINSTANCE или FARPRO C) или 0, чтобы указать, что должно быть сгенерировано исключение. Он также может выбросить свое собственное исключение или longjmp из крючка. Существуют перехватчики уведомлений и отказов.

Когда загружаемая с задержкой DLL не загружается, перехват вызывается с уведомлением dliFailLoadLib, содержащим подробности об операции загрузки и об ошибке. Хук может восстановиться после ошибки, вернув действительный HMODULE для использования помощником, или вернув 0, чтобы не выполнить операцию загрузки.

Если уведомление равно dliFailLoadLib, функция хука может вернуть:

  • 0, если он не может обработать ошибку.

  • HMODULE, если ловушка сбоя устранила проблему и загрузила библиотеку сам по себе.

Итак, если в сообщении об ошибке указано, что сбойная DLL - foo.dll, ваш хук может загрузить и вернуть HMODULE для bar.dll, и затем помощник загрузит все загруженные с задержкой функции foo.dll из bar.dll.

...