DllNotFoundException с HRESULT 0x8007007E при загрузке 64-битной DLL
Я скачал zlib и скомпилировал библиотеку как для Windows 32-битной, так и для Windows 64-битной библиотеки DLL. У меня сейчас zlibwapi.dll
а также zlibwapi64.dll
,
DLL-файлы копируются в папку моего приложения и на них ссылаются следующим образом:
[DllImport(@"zlibwapi.dll", EntryPoint = "uncompress", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = false)]
private static extern int uncompress32(
IntPtr dest,
ref uint destLen,
[In(), MarshalAs(UnmanagedType.LPArray)] byte[] source,
uint sourceLen
);
[DllImport(@"zlibwapi64.dll", EntryPoint = "uncompress", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = false)]
private static extern int uncompress64(
IntPtr dest,
ref uint destLen,
[In(), MarshalAs(UnmanagedType.LPArray)] byte[] source,
uint sourceLen
);
Во время выполнения я проверяю, 32-битный я или 64-битный, и вызываю соответствующую версию.
Это нормально работает, если я 32-битный, но 64-битная версия дает
Не удается загрузить DLL "zlibwapi64.dll": модуль не найден. (HRESULT исключение: 0x8007007E)
Я нашел много похожих вопросов в Интернете, и предполагаемая причина заключалась в том, что библиотека зависит от некоторых других библиотек, и именно эти библиотеки могут быть не найдены.
Это не похоже на случай:
- zlibwapi64.dll зависит только от Kernel32.dll и MSVCR90.dll. У меня есть установленная среда исполнения VS2008 C++, как 32-разрядная, так и 64-разрядная.
- Когда я пытаюсь загрузить zlibwapi64.dll из неуправляемого приложения C++, он не загружается. Это C#, который не может загрузить его.
Я попытался установить абсолютный путь к 64-битной DLL, это не помогает.
Как мне заставить это работать?
2 ответа
Это довольно простая ошибка типа "файл не найден", к сожалению, она не говорит вам явно, какую DLL она не может найти. Вы уже знаете о проблеме с зависимыми DLL. Обратите внимание, что вы можете избежать утомительной зависимости от msvcr90.dll, скомпилировав код с /MT
Вам нужно будет отладить проблему, и это требует понимания того, где она ищет библиотеки DLL. Одним из хороших инструментов является утилита SysInternals ProcMon, которая показывает, где именно ваша программа ищет файлы. Вы должны увидеть, как он проверяет DLL, просматривает каталоги PATH и не может найти файл.
К сожалению, ProcMon немного болтливый и имеет привычку утопить вас в данных. Более специализированным инструментом является GFlags.exe, инструмент, доступный в пакете Средства отладки для Windows. Эти дни включены в Windows SDK. Хранится в папке c:\program files (x86)\ средства отладки для windows\gflags.exe после его установки. Вы можете включить опцию "Показывать привязки загрузчика". В более поздних версиях Windows это говорит загрузчику Windows генерировать сообщения отладки при поиске DLL. Они появятся в окне "Вывод", когда вы включите неуправляемую отладку.
Сначала попробуйте ProcMon, гораздо проще начать.
И, конечно, подумайте о чисто управляемых решениях, чтобы вы не боролись с подобными проблемами при установке. Хорошие из них - DotNetZip и SharpZipLib, сделайте свой первый хит в Google.
Еще одним хорошим инструментом для изучения зависимостей Dll является обходчик зависимостей (зависит). Он смотрит на файл в статическом режиме, поэтому немного проще, чем при использовании монитора процесса.