在.NET 4.0中加载本机DLL时发生BadImageFormatException

时间:2013-11-20 20:16:37

标签: c# .net dllimport

我试图通过USB使用CAN设备,该设备附带一个原生DLL,需要由.NET C#类(供应商提供的源代码)包装,并包含在一个版本中项目。他们的示例应用程序面向.NET 2.0,其中我的应用程序面向.NET 4.0我能够在他们的示例应用程序中使用代码并调试一切就好了,但是,当我尝试调试我的应用程序时,我得到一个BadImageFormatException:

System.TypeInitializationException: The type initializer for 'TotalPhase.KomodoApi' threw an exception. ---> System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

他们的代码和我的代码之间的唯一区别似乎是他们的代码是为.NET 2.0构建的应用程序,并且(目前)我的代码在.NET 4.0中作为MSTest单元测试运行。两种解决方案都针对AnyCPU。我正在运行Windows 7 Ultimate 64位安装。即使从AnyCPU更改为x86也没有任何区别。如何在AnyCPU项目中加载此本机DLL?

1 个答案:

答案 0 :(得分:9)

如果在与本机DLL接口时获得BadImageFormatException,则几乎总是意味着您在64位CLR中运行时尝试与32位DLL接口,反之亦然。

运行示例应用程序时,任务管理器的“进程”选项卡的“图像名称”列中的进程是否为*32?这表明应用程序正在32位CLR中运行。检查您自己的应用程序。您正在测试的计算机可能只有32位.NET 2.0运行时,但是32位和64位.NET 4.0运行时,或者相反。

如果要使用.NET应用程序分发本机DLL,则应将启动项目设置为目标x86或x64(而不是AnyCPU),具体取决于本机库是32位还是64位。您始终可以同时提供32位和64位版本,并让安装程序根据客户端体系结构选择要安装的二进制文件。

或者,您可以发送具有不同文件名的32位和64位DLL,为每个版本定义单独的P / Invoke存根,并决定在运行时调用哪个。最简单的方法可能是将您的本机调用包装在一个接口(例如INativeMethods)中,并根据IntPtr.Size选择在运行时实例化的实现。使用此方法,您仍然可以定位AnyCPU。