是否有跨平台(x86和x64)PInvoke和Windows数据类型的权威指南?
我正在validationx64兼容性的一些代码。 以前我使用过PInvoke.net,但是我发现了x64方面的一些可疑声明。 所以现在,我:
- 查找API参考,例如MapViewOfFile
- 查找Windows数据类型定义
- 找到相应的.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;
好的…所以我猜那是IntPtr
或UIntPtr
。 本文有一个表,建议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方法; 在这些情况下,无论类型是有符号还是无符号都无关紧要,只要它的大小合适即可。
因此,一般规则是任何指针大小的值都变为IntPtr
, DWORD
和QWORD
变为U?Int32
和U?Int64
。
此外,如果它是32位机器上的32位和64位机器上的64位(例如ptrdiff_t),则必须使用IntPtr。