简体   繁体   English

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

[英]BadImageFormatException occurring when loading a native DLL in .NET 4.0

I'm attempting to use a CAN device over USB that comes with a native DLL that needs to be wrapped by a .NET C# class (source code provided by the vendor) that gets included in one's project. 我正在尝试使用USB上的CAN设备,该设备附带一个原生DLL,需要由.NET C#类(供应商提供的源代码)包装,该类包含在一个项目中。 Their sample applications target .NET 2.0 where my application targets .NET 4.0. 他们的示例应用程序面向.NET 2.0,其中我的应用程序面向.NET 4.0 I'm able to use the code in their sample apps and debug everything just fine, however, when I try to debug my application, I get a BadImageFormatException: 我能够在他们的示例应用程序中使用代码并调试一切就好了,但是,当我尝试调试我的应用程序时,我得到一个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)

The only differences between their code and mine appears to be that their code is an application built for .NET 2.0 and (currently) my code is running as an MSTest unit test in .NET 4.0. 他们的代码和我的代码之间的唯一区别似乎是他们的代码是为.NET 2.0构建的应用程序,并且(目前)我的代码在.NET 4.0中作为MSTest单元测试运行。 Both solutions target AnyCPU. 两种解决方案都针对AnyCPU。 I'm running on a Windows 7 Ultimate 64-bit install. 我正在运行Windows 7 Ultimate 64位安装。 Even changing from AnyCPU to x86 didn't make any difference. 即使从AnyCPU更改为x86也没有任何区别。 How can I get this native DLL to load in an AnyCPU project? 如何在AnyCPU项目中加载此本机DLL?

If you get a BadImageFormatException when interfacing with a native DLL, it almost always means that you are trying to interface with a 32-bit DLL while running in the 64-bit CLR, or vice versa. 如果在与本机DLL连接时遇到BadImageFormatException ,它几乎总是意味着您在64位CLR中运行时尝试与32位DLL接口,反之亦然。

When you run the sample applications, do the processes have *32 in the "Image Name" column of Task Manager's "Processes" tab? 运行示例应用程序时,进程是否在任务管理器的“进程”选项卡的“图像名称”列中有*32 That indicates the applications are running in the 32-bit CLR. 这表明应用程序正在32位CLR中运行。 Check your own application as well. 检查您自己的应用程序。 It is possible that the machine you are testing on only has a 32-bit .NET 2.0 runtime, but both 32-bit and 64-bit .NET 4.0 runtimes, or the other way around. 您正在测试的计算机可能只有32位.NET 2.0运行时,但是32位和64位.NET 4.0运行时,或者相反。

If you are distributing a native DLL with your .NET application, then you should set your startup project to target x86 or x64 (as opposed to AnyCPU), depending on whether the native libraries are 32-bit or 64-bit. 如果要使用.NET应用程序分发本机DLL,则应将启动项目设置为目标x86或x64(而不是AnyCPU),具体取决于本机库是32位还是64位。 You can always ship both 32-bit and 64-bit versions, and let the installer choose which binaries to install based on the client architecture. 您始终可以同时提供32位和64位版本,并让安装程序根据客户端体系结构选择要安装的二进制文件。

Alternatively, you can ship both 32-bit and 64-bit DLLs with different file names, define separate P/Invoke stubs for each version, and decide which one to call at runtime. 或者,您可以发送具有不同文件名的32位和64位DLL,为每个版本定义单独的P / Invoke存根,并决定在运行时调用哪个。 The easiest way to do this would probably be to wrap your native calls in an interface (eg, INativeMethods ) and choose which implementation to instantiate at runtime based on IntPtr.Size . 最简单的方法可能是将您的本机调用包装在一个接口(例如, INativeMethods )中,并根据IntPtr.Size选择在运行时实例化的实现。 With this method, you could still target AnyCPU. 使用此方法,您仍然可以定位AnyCPU。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM