Динамически связанная DLL загружается сразу после запуска приложения - PullRequest
0 голосов
/ 31 августа 2018

Я динамически связал libhunspell.dll (HunSpell) с моим приложением. Это работает, но есть глупая проблема, которую я не знаю, почему это происходит.

Даже прежде чем я использую LoadLibrary("path\\to\\libhunspell.dll");, чтобы загрузить и использовать его, при запуске приложения оно пытается загрузить библиотеку самостоятельно. Если я помещаю libhunspell.dll в путь, где находится мой главный исполняемый файл, он может загрузить его, в противном случае он сообщает об ошибке сразу после запуска приложения - Это приложение не удалось запустить из-за LIBHUNSPELL .DLL не был найден. Повторная установка приложения может решить эту проблему. , и приложение не запускается.

Я бы понял, если бы LoadLibrary использовал неверный путь, но это происходит, как только исполняется исполняемый файл, даже до выполнения первого оператора в WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) (я пытался установить точку останова, и она даже не дойти до него, так бывает раньше).

Таким образом, в результате я должен поместить libhunspell.dll в ту же папку, где находится исполняемый файл приложения, а не в путь, который я хочу.

Вероятно, это легко исправить, хотя я не знаю, что искать.

Итак, вопрос в том, как мне избежать его немедленной загрузки и подождать, пока я использую LoadLibrary вызов?

Вот как я связался, если это может помочь:

1) скомпилированный libhunspell.dll в Visual Studio 2015 (я использовал опцию / MT, чтобы статически связать его, чтобы у него не было распространяемого VC ++ в качестве зависимости).

2) создал библиотеку импорта (libhunspell.lib), используя implib.exe -a -c -f libhunspell.lib libhunspell.dll

3) связал это с исходным модулем .cpp, который использует его, используя #pragma comment(lib, "libhunspell.lib") (это RAD Studio 2010, поэтому .lib требуется в отличие от более новых версий).

4) позже в том же .cpp использовал LoadLibrary для загрузки этой библиотеки и использовал ее.

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Я полагаю, вы сделали Добавить в проект файл *.lib для вашей DLL . Это своего рода «статическая» связь, выполняемая при инициализации приложения (до создания ваших форм). Так что у него есть два недостатка.

  1. Вы DLL должны находиться в том же пути, что и файл Apps EXE
  2. Иногда DLL имя файла заблокировано (не может быть изменено)

Преимущество заключается в том, что вам не нужно выполнять какое-либо кодирование для загрузки DLL , поскольку VCL делает это за вас ... поэтому ваше приложение не должно содержать вызовов LoadLibrary,GetProcAddress, которые вы просто включаете *.h файл с объявлениями импорта пропперов ...

Для динамического связывания вам необходимо удалить *.lib из вашего проекта и использовать WinAPI LoadLibrary + GetProcAddress для загрузки DLL , как предложено josh poley . Вот пример:

Остерегайтесь / была (/ есть?) Ошибка в GetProcAddress, препятствующая загрузке всех функций из DLL в некоторых случаях. Особенно, если DLL имеет старое устаревшее искажение имен, количество функций велико, а DLL была создана на компиляторе, несовместимом с рассматриваемым исправлением.

0 голосов
/ 31 августа 2018

Путем связывания с заглушками импорта (libhunspell.lib) ОС загрузит DLL для вас, поскольку теперь она является статической зависимостью.

Один из подходов - указать библиотеку в качестве зависимости задержки загрузки: /DELAYLOAD:libhunspell.lib через параметры компоновщика. Затем вы можете вызвать LoadLibrary в DLL.

Единственный другой вариант - прекратить включение .lib в шаг компоновщика, что делает его действительно динамической зависимостью.

...