Внешнее исключение выдается в функции при использовании DLL из не папки приложения - PullRequest
2 голосов
/ 01 декабря 2011

У меня есть проблема, которую я не понимаю. Я использую DLL в своем приложении. Эта DLL требует других DLL, и у меня есть все из них. Если я помещаю библиотеки в папку с приложениями, все работает нормально.

Однако наличие нескольких DLL-библиотек в папке приложения выглядит довольно уродливо, поэтому я хотел переместить их в подпапку application \ lib.

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

Я изменил только одну строку кода:

Оригинальный код

DLLHandle := LoadLibrary(Pchar(ExtractFilePath(ParamStr(0)) + 'External.dll'))

код после изменения

DLLHandle := LoadLibrary(Pchar(ExtractFilePath(ParamStr(0)) + 'lib\External.dll'))

В обоих случаях DLLHandle имеет дескриптор после загрузки библиотеки. Я также не получаю никакой ошибки после вызова GetProcAddress( DLLHandle, '_SomeFunction@8')

Нет исключений, и возвращаемое значение GetLastError всегда равно 0.

У вас есть идеи, что может быть не так?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

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

Скорее всего, у вас есть вторичные зависимости DLL, которые не взаимодействуют. Таким образом, exe загружает штрафа, но затем A не загружается B. Вы можете отладить это дальше с Dependency Walker , работающим в режиме профиля. Вполне возможно, что вторичная DLL загружается с неявным связыванием, и это вызывает и исключение. Независимо от причины, Depenency Walker приведет вас к проблеме.

Хотя вы можете изменить переменную PATH, это обычно не рекомендуется. Если вы решите пойти по этому пути, то не изменяйте всю систему, просто измените среду исполняемого процесса во время выполнения до первого LoadLibrary. Это приемлемо до тех пор, пока все ваши ссылки на DLL явные с использованием GetProcAddress.

Все общепринятые рекомендации рекомендуют помещать ваши библиотеки DLL в ту же папку, что и исполняемый файл. Я бы повторил эту рекомендацию. Если вы сделаете это, то сможете использовать неявные ссылки, которые значительно упростят ваш код.

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

1 голос
/ 01 декабря 2011

Другие библиотеки DLL, которые необходимо загрузить, должны находиться в системном пути, чтобы Windows могла их найти. Ваше приложение может найти файл External.dll, поскольку вы явно определяете путь. Попробуйте добавить папку lib в системный путь.

...