为什么我的C++;interop可以在.NET4.5上工作,但不能在.NET4.5上工作 在我的项目中,我必须使用第三方C++ DLL(不COM)。我开发了一个接口C#dll,供我的主程序使用。以下是设置:

为什么我的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

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(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
targeting
x86
。如果以
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
targeting
x86
。如果以
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.5
AnyCPU
稍微做了一些修改,以避免您遇到的问题。默认情况下,即使在64位操作系统上,它也更喜欢在32位进程中执行。