【发布时间】:2012-08-10 19:04:48
【问题描述】:
今天我遇到了一个非常奇怪的问题,我能够解决,但我仍然不明白为什么会这样。这是场景:
编辑
我将场景更改为更简单: 我有一个执行代码的程序和 2 个 Importers,一个具有泛型类型的基类和另一个仅调用基方法并对其进行迭代的类 (ImplementingImporter)。 这是完整的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IEnumeratorLoadProblem {
class Program {
static void Main(string[] args) {
var importer = new ImplementingImporter();
try {
var data = importer.GetData().ToArray();
} catch (BadImageFormatException ex) {
Console.WriteLine("Why does this fail? " + ex.ToString());
}
Console.WriteLine("Press enter to quit");
Console.ReadLine();
}
}
class BaseClassImporter<T> {
public virtual IEnumerable<T> GetData() {
yield break;
}
}
class ImplementingImporter : BaseClassImporter<int> {
public override IEnumerable<int> GetData() {
// iterating seems to cause the problem
foreach(var dataByBaseImpl in base.GetData()) {
yield return dataByBaseImpl;
}
}
}
}
我收到以下错误:
System.BadImageFormatException:尝试加载程序 格式不正确。 (HRESULT 异常:0x8007000B)
当我将代码从使用的导入器更改为它时有效:
class ImplementingImporter : BaseClassImporter<int> {
protected override IEnumerable<int> GetData() {
return base.GetData();
}
}
不幸的是,我无法查看生成的 IL 代码,因为 ILSpy 和 Reflector.NET(版本 6)都显示了一个内部错误(我认为这是一个 ArgumentOutOfRangeException)。因为害怕使用ildasm,所以没有尝试直接看IL Code。
我猜这与生成的 IL 代码有关,但我想不出导致问题的场景。
有什么想法吗? 如果场景不够清晰,请发表评论,我会尽力使其更清晰。
编辑:
使用的 .NET 版本:4.0。该应用程序是使用 VS 2010 SP1 的 ConsoleApplication。 构建平台目标是 AnyCPu,但使用 x86 时也会出现问题。 我的机器有一个 64 位系统(Windows 7)。 使用 .NET 4.0 客户端配置文件时也会发生异常。
该示例是单个项目,没有使用外部/非托管库,因此不应出现建议的问题(例如,在运行 64 位时引用 32 位程序集)。
【问题讨论】:
-
此异常通常是当您处于 32/64 位进程中尝试加载其他“位”的 DLL 时。一个进程只能针对一个平台,并且一旦选择,只能加载同一平台的 DLL(一次 32 位,始终为 32 位 - 与 64 位相同)。确保您正在构建的 DLL 上的目标平台都是相同的,无论是 x86/x64 显式(但都相同)还是 AnyCPU 用于隐式选择位数。
-
这也是我的第一个猜测,所以我检查了选项并创建了一个项目来重现问题(我想当所有内容都在一个程序集中时,它不应该是构建问题)。我将在问题中添加一些关于使用的 .NET 版本等的其他信息
-
同样的规则适用于也在进程内运行的其他第三方托管和非托管 DLL。
-
该解决方案仅包含单个项目,不包含外部 dll。应该可以将给定的场景复制到一个文件中并运行它。也许我可以简化场景。
-
我更新了示例以重现问题。