为什么我的C++;interop可以在.NET4.5上工作,但不能在.NET4.5上工作 在我的项目中,我必须使用第三方C++ DLL(不COM)。我开发了一个接口C#dll,供我的主程序使用。以下是设置:
IDE:VS Express Desktop 2013 x64 Legacy.dll(C++)Interface.dll(C#.Net4.5 AnyCPU)Program.exe(C++)# .Net4.5(任何CPU) 这是我的互操作类:为什么我的C++;interop可以在.NET4.5上工作,但不能在.NET4.5上工作 在我的项目中,我必须使用第三方C++ DLL(不COM)。我开发了一个接口C#dll,供我的主程序使用。以下是设置:,c#,.net,windows,dll,interop,C#,.net,Windows,Dll,Interop,IDE:VS Express Desktop 2013 x64 Legacy.dll(C++)Interface.dll(C#.Net4.5 AnyCPU)Program.exe(C++)# .Net4.5(任何CPU) 这是我的互操作类: public static class Legacy { // Establish a connection with a protocol channel // extern “C” long WINAPI LegacyConnect(un
public static class Legacy
{
// Establish a connection with a protocol channel
// extern “C” long WINAPI LegacyConnect(unsigned long ProtocolID, unsigned long Flags, unsigned long *pChannelID)
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyConnect(Int32 ProtocolId, Int32 Flags, ref Int32 pChannelId);
// Terminate a connection with a protocol channel
// extern “C” long WINAPI LegacyDisconnect(unsigned long ChannelID)
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyDisconnect(Int32 ChannelId);
// General I/O control functions for reading and writing protocol configuration parameters (e.g. initialization, baud rates, programming voltages, etc.)
// extern “C” long WINAPI LegacyIoctl(unsigned long ChannelID, unsigned long IoctlID, void *pInput, void *pOutput)
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyIoctl(Int32 ChannelID, Int32 IoctlId, byte[] pInput, Int32 pOutput);
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyIoctl(Int32 ChannelID, Int32 IoctlId, ref SCONFIG_LIST pInput, Int32 pOutput);
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyIoctl(Int32 ChannelID, Int32 IoctlId, ref SCONFIG_HWTYPE_BAUDRATE pInput, Int32 pOutput);
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyIoctl(Int32 ChannelID, Int32 IoctlId, IntPtr pInput, Int32 pOutput);
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyIoctl(Int32 ChannelID, Int32 IoctlId, ref int pInput, Int32 pOutput);
// Read message(s) from a protocol channel
// extern “C” long WINAPI LegacyReadMsgs(unsigned long ChannelID, Legacy_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout)
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyReadMsgs(Int32 ChannelID, ref Legacy_MSG pMsg, ref Int32 pNumMsgs, Int32 TimeOut);
// Write message(s) to a protocol channel
// extern “C” long WINAPI LegacyWriteMsgs(unsigned long ChannelID, Legacy_MSG *pMsg, unsigned long *pNumMsgs, unsigned long Timeout)
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyWriteMsgs(Int32 ChannelID, ref Legacy_MSG pMsg, ref Int32 pNumMsgs, Int32 TimeOut);
[DllImport("Legacy.dll")]
public static extern LegacyErrCodes LegacyWriteMsgs(Int32 ChannelID, IntPtr pMsg, ref Int32 pNumMsgs, Int32 TimeOut);
}
两个.Net项目最初的目标都是Framework4.5,平台设置为AnyCPU,一切正常
我被要求将解决方案降级到目标Framework 4,幸运的是,Interface.dll中不需要修改任何代码,Program.dll中也不需要修改任何与其使用相关的内容,因此设置变成:
Legacy.dll(C++)Interface.dll(C#.Net4 AnyCPU)Program.exe(C#.Net4
任意CPU)
从此以后,我得到了一个<强> BaDimaFrimeExtExabue>强>每当我的IngField.dll试图调用C++ DLL的函数时。 我找到了解决方法:如果我将调用程序(program.exe)设置为仅针对x86CPU,它将再次工作
Legacy.dll(C++)Interface.dll(C#.Net4 AnyCPU)Program.exe(C#.Net4 x86)我只是一个高级开发人员,所以我完全不知道这个问题。为什么会这样?这是将Program.exe配置恢复到任何CPU的一种方法吗?如果不是,这是否真的意味着即使在64位机器上,我的程序也将以32位运行?
BadImageFormatException
很可能是因为试图加载具有错误“位”的可执行文件(例如,在64位进程中加载32位DLL)。如果Legacy.dll
是一个32位的dll(它似乎基于您提供的信息),您只需编译Program.exe
targetingx86
。如果以AnyCPU
为目标,则Program.exe
将在64位操作系统上的64位进程中执行,如果加载32位DLL,则不希望发生这种情况。实际上,在.NET 4.5中,这一点稍有改变,因此可执行项目的默认值是使用AnyCPU
,但使用“首选32位”(),这解释了为什么只有降级到.NET 4时才会遇到问题
这真的意味着即使在64位机器上,我的程序也会以32位运行吗
是的,您的程序加载32位传统DLL,即使在64位操作系统上也必须在32位进程中执行。只有获得64位版本的旧DLL,程序才能在64位进程中执行
通常,如果您的代码依赖于仅以32位或64位形式存在的DLL(通常是在执行互操作时),则应避免将目标设置为AnyCPU
。相反,任何具有32位依赖项的程序集都应该以x86为目标,并且这个特定的目标应该一直沿着依赖项链流向可执行项目
BadImageFormatException
很可能是由于尝试加载具有错误“位”的可执行文件(例如,在64位进程中加载32位DLL)而导致的。如果Legacy.dll
是一个32位的dll(它似乎基于您提供的信息),您只需编译Program.exe
targetingx86
。如果以AnyCPU
为目标,则Program.exe
将在64位操作系统上的64位进程中执行,如果加载32位DLL,则不希望发生这种情况。实际上,在.NET 4.5中,这一点稍有改变,因此可执行项目的默认值是使用AnyCPU
,但使用“首选32位”(),这解释了为什么只有降级到.NET 4时才会遇到问题
这真的意味着即使在64位机器上,我的程序也会以32位运行吗
是的,您的程序加载32位传统DLL,即使在64位操作系统上也必须在32位进程中执行。只有获得64位版本的旧DLL,程序才能在64位进程中执行
通常,如果您的代码依赖于仅以32位或64位形式存在的DLL(通常是在执行互操作时),则应避免将目标设置为AnyCPU
。相反,任何具有32位依赖项的程序集都应该以x86为目标,并且这个特定的目标应该一直沿着依赖项链流向可执行项目
好的,我走这边。但是你知道为什么它能在4.5 frmk上完美地与AnyCPU一起工作吗?@ironslaug:In.NET 4.5
AnyCPU
稍微做了一些修改,以避免您遇到的问题。默认情况下,它更喜欢在32位进程中执行,即使在64位操作系统上也是如此。但是你知道为什么它能在4.5 frmk上完美地与AnyCPU一起工作吗?@ironslaug:In.NET 4.5AnyCPU
稍微做了一些修改,以避免您遇到的问题。默认情况下,即使在64位操作系统上,它也更喜欢在32位进程中执行。