加载 32 位 DLL 时出现 BadImageFormatException,目标是 x86

Posted

技术标签:

【中文标题】加载 32 位 DLL 时出现 BadImageFormatException,目标是 x86【英文标题】:BadImageFormatException when loading 32 bit DLL, target is x86 【发布时间】:2011-02-13 06:54:24 【问题描述】:

我有一个 DLL (FreeType),它肯定是 32 位的(头文件:IMAGE_FILE_MACHINE_I386)。

我想在 C# 代码中使用它,使用 DllImport。

我的应用程序的目标是 x86,IntPtr.Size 是 4,进程是 32 位。

但我得到 BadImageFormatException(来自 HRESULT 的异常:0x8007000B)。有什么问题?

当然我使用的是 64 位 Windows 7。

【问题讨论】:

投票结束是“不是一个真正的问题”——这个问题的基础是误解; OP 发现有问题的 DLL 加载正确 【参考方案1】:

据我了解,专门为 x86 构建并在 64 位操作系统中运行的程序集只能加载为 x86 构建的库,否则将引发 BadImageFormatException。在 64 位操作系统中,为 Any CPU 或 x64 构建的程序集在尝试加载 x86 库时会引发相同的异常。

因此,假设没有发生任何令人难以置信的奇怪事情,我会确保您已通过打开项目属性并单击“构建”选项卡将应用程序设置为构建为 x86。确保“平台目标”设置为“x86”而不是任何 CPU。

或者,您可以尝试查找 64 位版本的 DLL 以进行测试。

【讨论】:

我 100% 确定我的 C# 应用程序是 32 位的。我什至用 CORFLAGS 来检查它:版本:v2.0.50727 CLR 标题:2.5 PE:PE32 CorFlags:3 ILONLY:1 32BIT:1 签名:0 @Eric Smith 我遇到了同样的问题......这解决了它。非常感谢! 是的,反之亦然。例如,如果 64 位应用程序尝试加载 32 位 DLL。【参考方案2】:

使用 Build -> Platform 中的“Any CPU”选项重新编译 dll。

【讨论】:

任何 CPU 都不在我的列表中。【参考方案3】:

好吧,好像是个误报。它与位数无关,只是缺少freetype所依赖的其他DLL。但是,错误消息可能更有帮助。

【讨论】:

这一半解决了我的 BadImageFormatException 问题 - 我忘记复制依赖的 DLL。不幸的是,现在我在原始 DLL 上得到了 DllNotFoundException ... @jarmond 确保你构建了发布版本(不是调试)【参考方案4】:

从 C# 调用 64 位 C Dll 时遇到相同的错误。我不得不手动将 C# Properties->Build->Platform targetAny Cpu 更改为 x64。显然Any Cpu 有时是 NoCpu。

【讨论】:

【参考方案5】:

此外,Web 应用程序需要解决在 IIS 7 中运行 32 位应用程序。请参阅 http://www.fishofprey.com/2009/04/badimageformatexception-in-iis-70-on-64.html

【讨论】:

【参考方案6】:

我遇到了类似的错误。 我可以通过将用于调试的 ucrtbase.dll 或 ucrtbased.dll 以及用于调试的 vcruntime140.dll 或 vcruntime140d.dll 添加到可执行文件的目录中来解决它。 我认为 140 取决于您使用的 Visual Studio 的版本号。

ucrtbase.dll 通常位于C:\Windows\System32。 vcruntime140.dll 位于C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x86\vcruntime140.dll

您可以在这里找到更多信息:http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx

【讨论】:

【参考方案7】:

我怀疑自从第一次提出这个问题以来的 8 年里,这个异常的常见原因已经发生了变化。在我使用 VS 2017 的设置中,我发现取消选中“首选 32 位”解决了这个问题:

Uncheck "Prefer 32-bit" in the Build options

这使得我从 C++ 构建的 64 位 DLL 可以正确加载。相反,选中此选项应该可以正确加载 32 位 DLL。

【讨论】:

【参考方案8】:

当您使用 Visual Studio 构建本机应用程序/DLL 时,它会获得对该版本 Visual Studio 的“可再发行”包的依赖。其中包含诸如 msvcr100.dllmsvcp100.dll 之类的 DLL(对于 100 的各种值)。

就我而言,我在目标机器的Windows/system32 目录中看到了这些DLL,所以我认为一切都很好。原来那些 DLL 是 x64 的!我不知道为什么一个名为 system32 的目录包含 64 位 DLL。因此,我在我的 Visual Studio 2010 目录中搜索了名为 msvc*.dll 的所有内容,并找到了 x86 版本的 msvcr100.dllmsvcp100.dll。我将它们复制到目标机器(在可从我的程序路径访问的位置),一切都很好。

我希望这可以帮助其他人面对微软的疯狂。

【讨论】:

【参考方案9】:

您在 C# 项目中使用属性,并将“平台目标”更改为 x64。 enter image description here

【讨论】:

【参考方案10】:

您可以尝试检查选项“属性”->“构建”->“允许不安全代码”。

【讨论】:

【参考方案11】:

我在 MS Visual C# Express 2010 中遇到了同样的异常。我使用 Dependency Walker 和 MiTeC EXE Explorer 检查了所有构建的 .dll 和 .exe 文件,一切都是为 32 位构建的!

最后,我的 .csproj 文件中缺少以下行:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'MY_CONFIG|x86'">
    ...
    <PlatformTarget>x86</PlatformTarget>
    ...
</PropertyGroup>

我不知道它为什么不见了……我猜 MS Visual C# Express 2010 不是没有错误的;)

【讨论】:

以上是关于加载 32 位 DLL 时出现 BadImageFormatException,目标是 x86的主要内容,如果未能解决你的问题,请参考以下文章

将 c# 应用程序打开到另一台电脑时出现无法加载 ace.dll32 的错误

oracle数据库使用plsql(64位)时出现的问题

VC++程序调试时出现“ 下面的框架可能不正确和/或缺失,没有为 kernel32.dll 加载符号”怎么回事?

将数组移交给 C# 中动态加载的 C++ DLL 时出现 System.AccessViolationException

从系统(SysWOW64)目录外部注册 32 位 COM 时出现问题

在Python中加载DLL时出现Windows错误1114