Загрузка DLL из другого каталога при запуске программы

моя основная проблема заключается в следующем: моя программа (MyProgram.exe) имеет зависимость от DLL из другой программы (OtherProgram), и я пытаюсь избежать переупаковки новой DLL каждый раз при обновлении OtherProgram. Я бы хотел иногда.exe ссылка в DLL OtherProgram при запуске, но я не совсем уверен,что Windows позволяет это. Поэтому, если есть какой-то обходной путь, который также был бы приемлемым.

и только для некоторого фона, платформа Windows 7 x64, и Иногда.exe работает нормально, когда я создаю символическую ссылку в MyProgram.exe каталог проекта в DLL в каталоге установки OtherProgram. Когда я пытаюсь запустить его без символической ссылки, я получаю "программа не может запускаться, потому что OtherProgramDLL.dll отсутствует в вашем компьютере " ошибка.

любые советы или ссылки на соответствующую информацию с благодарностью!

EDIT: уточнение: DLL не связана во время компиляции, эта проблема возникает во время выполнения

6 ответов


в мире Windows существует два типа динамической компоновки:

  1. Загрузки связывание - это когда DLL загружается автоматически при запуске программы. Windows находит эту DLL, используя конкретный алгоритм, который я рассмотрю ниже.
  2. Времени линковка-это когда вы в частности, загрузите DLL, вызвав LoadLibrary в коде. Аналогичные правила применяются к способу поиска библиотеки, но можно указать полный или относительно квалифицированный путь для управления поиском.

в случае связывания нагрузки, MS рекомендует, чтобы библиотеки DLL вашей программы хранились и загружались из того же каталога, из которого загружается ваше приложение. Если это вообще выполнимо, это, вероятно, ваш лучший вариант.

Если это не работает, есть несколько других вариантов,описанные здесь. Один использовать порядок поиска, поставив ДЛЛ либо в рабочем каталоге, либо в каталоге, из которого было загружено приложение.

Вы можете изменить рабочий каталог приложения:

  1. создайте ярлык для вашего приложения.
  2. откройте свойства ярлыка
  3. отредактируйте свойство "Start in" с каталогом, в котором находится DLL.

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

другие варианты для связывать нагрузк-времени включают:

  • добавление манифеста в ваше приложение, которое указывает, где ваш зависимый сборки или,
  • задание PATH.

вы можете добавить каталог, в котором находится dll, в PATH переменные среды.


можно использовать LoadLibrary, но вам понадобится способ гарантировать местоположение DLL. Это Википедия статьи предоставляет хороший пример того, как использовать DLL после его загрузки.


я боролся с той же проблемой, а также нашел тупик с предлагаемыми методами, такими как LoadLibrary, SetDllDirectory, Qt addLibraryPath и другие. Независимо от того, что я пытался, проблема по-прежнему заключалась в том, что приложение проверяло библиотеки (и не находило их) перед фактическим запуском кода, поэтому любое решение кода было обречено на неудачу.

я почти отчаялся, но затем обнаружил чрезвычайно простой подход, который также может быть полезен в таких случаях, как ваш:использовать a пакетный файл! (или аналогичный загрузчик перед фактическим приложением)

пакетный файл Windows для такой цели может выглядеть так:

@echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>

/ edit: просто увидел @SirDarius комментарий ответ Лучиана который описывает этот путь, так что просто возьмите мой пакетный код бит в качестве ссылки, и все кредиты идут к нему.


используйте символические ссылки на исполняемые файлы третьей стороны

Я нашел подход, защищаемый Аарон Margosis полезное. См.:

использование соединений NTFS для устранения проблем совместимости приложений в 64-разрядных версиях Windows

по существу, создайте символические ссылки на каждый из зависимых исполняемых файлов третьей стороны. Поместите эти символические файлы ссылок В и среди ваших собственных зависимых исполняемых файлов. Кроме изменения имени файла к целям, "мягкие" символические ссылки разрешат зависимости времени загрузки, даже если цель ссылок будет изменена будущими обновлениями.


У меня такая же проблема с одним приложением я работаю на.

Я не хочу использовать загрузку во время выполнения, потому что есть десятки функций, для которых мне нужно вручную создать указатель функции.

упоминание г-на Диблинга о файле манифеста открыло для меня новую дверь, но я с грустью узнал, что самая старая версия windows, которая поддерживает эту функцию, - Windows 7. Он даже не будет работать на Vista.

короче говоря, друг, знакомый с Windows Разработка приложений сказал мне, чтобы посмотреть DLL с задержкой загрузки, который оказывается, чтобы решить проблему отлично с минимальными усилиями. Он задерживает загрузку библиотеки DLL до точки, которую вы вручную делаете, или при первом вызове ее функции. Поэтому вам просто нужно добавить свой путь DLL в путь поиска, прежде чем это произойдет, где SetDllDirectory помогает.

вот шаги, чтобы заставить его работать:

1) укажите DLL для загрузки с задержкой компоновщик, либо через ваш makefile, cmake или VS Property page (Компоновщик->вход VS2015)

2) вызов SetDllDirectory в начале вашей программы, прежде чем будет сделан какой-либо вызов DLL.

DLL с задержкой поддерживается вплоть до VC6. SetDllDirectory поддерживается после XP SP1.