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

时间:2012-05-27 13:13:42

标签: c# visual-studio-2008 pinvoke dllimport 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的绝对路径,但没有帮助。

如何让它发挥作用?

2 个答案:

答案 0 :(得分:11)

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

编译代码来避免对msvcr90.dll的厌恶依赖

您需要调试问题,这需要深入了解它在寻找DLL的位置。一个很好的工具是SysInternals' ProcMon utility,它可以准确显示程序查找文件的位置。您应该看到它正在探测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,他们的第一个谷歌热门。

答案 1 :(得分:2)

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

http://www.dependencywalker.com/