映射平台特定的可互操作类型

本文关键字:互操作 类型 平台 映射 | 更新日期: 2023-09-27 18:30:53

Windows 数据类型参考列出了以下类型:

#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,但是我想了解什么是真正的最佳选择。

言论

问题

你想解决什么问题?
答:通常将窗口数据类型映射到 .NET,尽可能接近以支持将来的 PInvoke 操作。

问题:PInvoke 与这个问题有什么关系?
答:Windows 数据类型是将托管数据正确映射到 PInvoke/d(非托管)签名(将来使用)

所必需的

例:

本地声明:

LRESULT WINAPI SendMessage(
  _In_  HWND hWnd,
  _In_  UINT Msg,
  _In_  WPARAM wParam,
  _In_  LPARAM lParam
);

调用声明变体:

[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 上运行

映射平台特定的可互操作类型

INT_PTRLONG_PTR的大小与指针相同。因此,它们在 32 位目标中为 32 位宽,在 64 位目标中为 64 位宽。在 C# 中使用 intlong 是完全错误的,因为它们具有固定的大小。INT_PTRLONG_PTR到 C# 的正确转换为 IntPtr

同样,对于无符号变体,请使用 UIntPtr