是否有跨平台(x86和x64)PInvoke和Windows数据类型的权威指南?

我正在validationx64兼容性的一些代码。 以前我使用过PInvoke.net,但是我发现了x64方面的一些可疑声明。 所以现在,我:

  1. 查找API参考,例如MapViewOfFile
  2. 查找Windows数据类型定义
  3. 找到相应的.NET类型。

这是第3步,我想要一个明确的参考

举个例子:

LPVOID WINAPI MapViewOfFile( __in HANDLE hFileMappingObject, __in DWORD dwDesiredAccess, __in DWORD dwFileOffsetHigh, __in DWORD dwFileOffsetLow, __in SIZE_T dwNumberOfBytesToMap ); 

返回值为LPVOID,定义为:

LPVOID

指向任何类型的指针。

此类型在WinDef.h中声明如下:

 typedef void *LPVOID; 

好的…所以我猜那是IntPtrUIntPtr 。 本文有一个表,建议LPVOID应映射到IntPtr或UIntPtr。 好。

接下来,HANDLE。

处理

对象的句柄。

此类型在WinNT.h中声明如下:

typedef PVOID HANDLE;

好的,HANDLE是一个PVOID。

PVOID

指向任何类型的指针。

此类型在WinNT.h中声明如下:

typedef void * PVOID;

嗯,听起来像IntPtr

接下来,DWORD

DWORD

一个32位无符号整数。 范围是0到4294967295十进制。

此类型在WinDef.h中声明如下:

 typedef unsigned long DWORD; 

好的,无符号长0到4294967295,所以这是一个uint ,但在这里它建议Int32或UInt32。 Int32将无法存储超过2,147,483,648的任何值。 所以那张桌子非常可疑。

最后,我们有SIZE_T,它被定义为ULONG_PTR,根据平台(下面的定义),它可以是32位或64位长签名。 本文 (及后续 )总结您应该使用IntPtr,因为它将处理变量大小。

SIZE_T

指针可指向的最大字节数。 用于必须跨越指针的整个范围的计数。

此类型在BaseTsd.h中声明如下:

 typedef ULONG_PTR SIZE_T; 

ULONG_PTR

无符号LONG_PTR。

此类型在BaseTsd.h中声明如下:

 #if defined(_WIN64) typedef unsigned __int64 ULONG_PTR; #else typedef unsigned long ULONG_PTR; #endif 

一个32位有符号整数。 范围是-2147483648到2147483647十进制。

此类型在WinNT.h中声明如下:

 typedef long LONG; 

INT64

64位有符号整数。 范围是-9223372036854775808到9223372036854775807十进制。

此类型在BaseTsd.h中声明如下:

 typedef signed __int64 INT64; 

因此,虽然我可以查找每个Windows数据类型的定义,然后根据大小,符号以及它是否同时适用于x86和x64找到相应的.NET数据类型,但它并不理想。

是否有一个明确的参考(不是pinvoke.net)与一个良好的映射表,是最新的x64?

将本机数据类型映射到托管类型时,重要的是大小和一致性。

签名与无符号类型的选择仅在解释托管值时才有意义。
他们都被编组为原始位。

在大多数情况下,您只需将值从一种API方法传递给另一种API方法; 在这些情况下,无论类型是有符号还是无符号都无关紧要,只要它的大小合适即可。

因此,一般规则是任何指针大小的值都变为IntPtrDWORDQWORD变为U?Int32U?Int64

此外,如果它是32位机器上的32位和64位机器上的64位(例如ptrdiff_t),则必须使用IntPtr。