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

时间:2014-11-18 12:56:02

标签: c# c++ .net interop pinvoke

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如何与此问题相关?
答案:要将托管数据正确映射到PInvoke / d(非托管)签名(将来使用),需要使用Windows数据类型

示例:

原生声明:

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

1 个答案:

答案 0 :(得分:1)

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

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