加载 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 target
从 Any 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.dll
和 msvcp100.dll
之类的 DLL(对于 100 的各种值)。
就我而言,我在目标机器的Windows/system32
目录中看到了这些DLL,所以我认为一切都很好。原来那些 DLL 是 x64 的!我不知道为什么一个名为 system32
的目录包含 64 位 DLL。因此,我在我的 Visual Studio 2010 目录中搜索了名为 msvc*.dll
的所有内容,并找到了 x86 版本的 msvcr100.dll
和 msvcp100.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 的错误
VC++程序调试时出现“ 下面的框架可能不正确和/或缺失,没有为 kernel32.dll 加载符号”怎么回事?
将数组移交给 C# 中动态加载的 C++ DLL 时出现 System.AccessViolationException