【发布时间】:2017-09-22 11:23:47
【问题描述】:
我有一个在 C# 代码中使用的非托管处理程序,委托定义如下
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int Callback (arguments)
它在 32 位版本中运行良好,我在问我在 64 位版本中必须进行哪些更改。包含处理程序的 dll 的 C 标头将所有函数定义为 __stdcall 如果 WIN32 和 __fastcall 如果 WIN64(即 dll 有 32 位和 64 位版本)。但在 NET 文档中,据说不支持 fastcall。我不明白这一切意味着什么,我应该如何更改(或不更改)64 位代码?
【问题讨论】:
-
使用 32 位版本,因为 64 位版本是 fastcall 并且网络文档说不支持 fastcall。
-
dll 和 C 头文件是我买的硬件附带的,我还没写。所以我知道您的 -1 是针对硬件供应商的。
-
编写使用
__stdcall的非托管包装器并转发到__fastcall版本(或使用 C++/CLI 立即将这些函数公开为托管函数),反之则用于回调(传递__fastcall委托给调用__stdcall托管回调的非托管代码)。如果有很多函数,您可能不想手动执行此操作,因此可能需要一些代码来生成它们。 -
只有当 32 位版本无法在 64 位 Windows 上运行时才需要所有这些(如果它直接与驱动程序接口可能就是这种情况)。如果可以,只需将您的托管代码编译为“首选 32 位”并专门使用 32 位版本,这会简单得多。
-
制造商可能根本不关心 .NET 代码与 DLL 的接口。在非托管代码中,这根本不是问题,因为您#include 标头然后离开了。由于调用约定是(预先提供的)标头的一部分,因此无需修改源。如果供应商担心托管代码,他们会自己提供 API。构建硬件和编写驱动程序已经够难了——托管代码是别人的问题。
标签: c# pinvoke 32bit-64bit unmanaged