加载64位dll时,带有HRESULT 0x8007007E的DllNotFoundException

我下载了zlib并将该库编译为Windows 32位和Windows 64位dll。 我现在有zlibwapi.dllzlibwapi64.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位。
  • 当我尝试从非托管C ++应用程序加载zlibwapi64.dll时,它没有加载任何问题。 C#无法加载它。

我试过设置64位dll的绝对路径,它没有帮助。

我如何使其工作?

这是一个相当基本的“找不到文件”的错误,遗憾的是它并没有明确地告诉你它找不到什么DLL。 您已经了解了依赖DLL的问题。 请注意,您可以通过使用/ MT编译代码来避免对msvcr90.dll的厌恶依赖

您需要调试问题,这需要深入了解它在寻找DLL的位置。 一个很好的工具是SysInternals的ProcMon实用程序 ,它可以准确显示程序查找文件的位置。 您应该看到它正在探测DLL,搜索PATH的目录并且无法找到该文件。

不幸的是,ProcMon有点健谈,并且习惯在数据中淹没你。 一个更专用的工具是GFlags.exe,这是一个可从Debugging Tools for Windows软件包获得的工具。 这些天包含在Windows SDK中。 安装后,存储在c:\ program files(x86)\ windows \ gfl​​ags.exe的调试工具中。 您可以打开“显示加载程序快照”选项。 在以后的Windows版本中,它告诉Windows加载程序在搜索DLL时生成调试消息。 启用非托管调试时,它们将出现在“输出”窗口中。

首先尝试ProcMon,更容易开始。

当然,考虑纯托管解决方案,这样您就不会遇到这些安装问题。 好的是DotNetZip和SharpZipLib,他们的第一个谷歌热门。

检查Dll依赖关系的另一个好工具是Dependency walker(依赖)。 它以静态方式查看文件,因此比使用进程监视器更容易。

http://www.dependencywalker.com/