7

我下载了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。我确实安装了 32 位和 64 位的 VS2008 C++ 运行时。
  • 当我尝试从非托管 C++ 应用程序加载 zlibwapi64.dll 时,它加载没有问题。是 C# 无法加载它。

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

我如何使它工作?

4

2 回答 2

12

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

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

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

首先尝试 ProcMon,更容易上手。

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

于 2012-05-27T13:50:09.773 回答
3

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

http://www.dependencywalker.com/

于 2012-05-27T14:25:14.700 回答