我正在.NET 3.5 中编写一个程序,在某些地方必须走出去并从硬件 API 执行代码。这一切都很好,并且可以在 32 位 Windows 7、Windows XP 等中工作。问题出现在 64 位 Windows 7 上。
我在“任何 CPU”中编译,它确实在 Windows 7 64 位上以 64 位运行。因此,要与这件硬件接口,我必须用非托管 C++ 编写自己的包装 DLL。
所以,在我全部在 32 位下工作后,我将开关切换到 64 位,这就是问题所在。我遇到的问题与 Stack Overflow 问题“试图加载格式不正确的程序”几乎完全相反,即使平台相同......在那个问题中,他正试图获取他的代码在 Windows 7 上以 32 位运行(强制运行)。
好的,现在,我不想这样做,因为这块硬件有一个 64 位 API。所以,我用 64 位编译了我的代码,然后经过大量试验和错误,我得到了64 位正确的LINK,我有一个纯 64 位本机 C++ DLL,并Depends.exe
确认了这一点。现在,Depends.exe
也将供应商的 DLL 文件显示为纯 64 位。这很好,因为第一次代码不起作用,我开始与制造商一起研究,他们在我的帮助下更新了很多代码,或者我应该用我的问题说...... :)
因此,长话短说,我已将其分解为尽可能简单的设置。我的 DLL 文件 HW API.dll
(也是本机 C++)和一个 .NET 应用程序来调用它们,使用相同的P/Invoke语法,并作为 64 位版本调用......
我的电话,仅供参考,如下所示:
[DllImport("xBiometrics.dll", ExactSpelling=true, SetLastError=true)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern Int32 bioScanOpenDevice();
现在,当我尝试从 .NET 调用此代码时,出现异常错误:
"System.BadImageFormatException:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)"
这让我相信 32 位的某些东西在某种程度上会产生干扰……我怎么可能说出来呢?我的意思是,是的,我已经查看了资源浏览器,并确保 DLL 文件是从正确的位置加载的,并且再次以 64 位编译它们,并且 .NET 应用程序以 64 位运行,即使它是为“任何 CPU”编译的。我已经验证了这一切...
我对这里的某些事情完全愚蠢吗?我是否错过了它告诉我们 P/Invoke 不适用于 64 位或其他东西的段落?如果我这样做了,为什么会抛出错误的图像格式异常?
我正在做的事情是否可能?64 位 .NET 应用程序可以加载和调用 64 位本机 DLL 文件吗?那个 DLL 文件可以动态链接到另一个本机 64 位 DLL 文件吗?如果我使用托管的 64 位 DLL 文件作为楔形 DLL 文件会有所不同吗?由于硬件供应商的 DLL 文件中的一些调用,我只使用了一个楔形 DLL 文件。他们将 void 指针传递给缓冲区,并且在 C# 中这样做太复杂了(必须检查“允许不安全代码”等)所以,我的楔形想法效果更好......我做了所有C++ 中的繁重工作并将更多结构化数据传回 C# 代码。