是否有跨平台(x86和x64)PInvoke和windows数据类型的明确指南
本文关键字:数据类型 windows 跨平台 x86 是否 x64 PInvoke | 更新日期: 2023-09-27 18:24:41
我正在验证x64兼容性的一些代码。以前我使用过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将无法存储超过2147483648的任何值。所以那张桌子很可疑。
最后,我们有SIZE_T,它被定义为ULONG_PTR,根据平台的不同,它可以是32或64位带符号的长(定义如下)。本文(以及后续文章)得出结论,您应该使用IntPtr,因为它将处理可变大小。
尺寸_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
LONG
一个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方法传递到另一个方法;在这些情况下,类型是有符号的还是无符号的并不重要,只要大小合适即可。
因此,一般规则是,任何指针大小的值都变为IntPtr
,并且DWORD
和QWORD
分别变为U?Int32
和U?Int64
。