映射平台特定的互操作类型
Posted
技术标签:
【中文标题】映射平台特定的互操作类型【英文标题】:Mapping platform specific interoperable types 【发布时间】:2014-11-18 12:56:01 【问题描述】:Windows Data Types 引用列出了以下类型:
#if defined(_WIN64)
typedef __int64 INT_PTR;
#else
typedef int INT_PTR;
#endif
#if defined(_WIN64)
typedef __int64 LONG_PTR;
#else
typedef long LONG_PTR;
#endif
由于 .NET(大部分)取消了预处理器指令,因此很难准确地映射这些指令。我可以看到两个选项,我想知道哪个最好:
使用 IntPtr,因为它是特定于平台的
using INT_PTR = System.IntPtr;
using LONG_PTR = System.IntPtr;
使用更大的整数,以防我们在 x64 上运行
using INT_PTR = System.Int64;
using LONG_PTR = System.Int64;
我的直觉是使用IntPtr
而不是Int64
,但是我想了解一下什么才是真正的最佳选择。
备注
问题:您要解决什么问题? 答案: 通常将 windows 数据类型映射到 .NET,尽可能紧密地支持未来的 PInvoke 操作。
问题: PInvoke 与此问题有何关联? 答案: 需要 windows 数据类型才能将托管数据正确映射到 PInvoke/d(非托管)签名(未来使用)
示例:
土著宣言:
LRESULT WINAPI SendMessage(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
PInvoke 声明变体:
[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern IntPtr SendMessage(
[In] IntPtr hWnd,
[In] uint Msg,
[In] UIntPtr wParam,
[In] IntPtr lParam
);
[DllImport("user32.dll", CallingConvention = CallingConvention.Winapi)]
public static extern long SendMessage(
[In] IntPtr hWnd,
[In] uint Msg,
[In] ulong wParam,
[In] long lParam
);
在上面的示例中,第一个实例使用 IntPtr 和 UIntPtr(特定于平台)类型,而第二个实例使用 long 和 ulong,“以防万一”在 x64 上运行
【问题讨论】:
您要解决什么问题? PInvoke 与这个问题有什么关系? @AlexFarber - 见备注 Agiin,不清楚。IntPtr
具有正确的 32 位和 64 位大小。 PInvoke 调用的 Native Dll 的位数相同,因此 IntPtr 的大小与 void* 相同
@AlexFarber 因此说我想 PInvoke 使用 INT_PTR 的东西;使用实现是否特定(我需要根据实现选择正确的 .NET 数据类型,而不是一般使用 IntPtr vs Int32/Int64)?
您不能从 64 位进程中 PInvoke 32 位 Dll,也不能从 32 位进程中 PInvoke 64 位 Dll。所以,如果你 PInvoke 带有参数 INT_PTR 的原生 Dll,将其声明为 IntPtr,两者的大小将是相同的。
【参考方案1】:
INT_PTR
和 LONG_PTR
与指针大小相同。因此,它们在 32 位目标中为 32 位宽,在 64 位目标中为 64 位宽。在 C# 中使用 int
或 long
是完全错误的,因为它们具有固定的大小。 INT_PTR
和 LONG_PTR
到 C# 的正确翻译是 IntPtr
。
同样,对于未签名的变体,使用UIntPtr
。
【讨论】:
问题...如何在 C# 中映射 HALF_PTR(32 位机器上为 16 位,64 位机器上为 32 位)? 这种东西还存在吗?! 根据 Windows 数据类型参考,是的。虽然它对我来说似乎很奇怪 - 甚至可能不会在任何地方使用 没有可匹配的 C# 类型。我从未见过这种类型的用途。以上是关于映射平台特定的互操作类型的主要内容,如果未能解决你的问题,请参考以下文章