我正在验证一些代码的 x64 兼容性。以前我使用过 PInvoke.net,但我发现了一些关于 x64 的可疑声明。所以现在,我:
- 查找 API 引用,例如 MapViewOfFile
- 查找 windows data type定义
- 找到相应的 .NET 类型。
这是第 3 步,我想要一个明确的引用
举个例子:
LPVOID WINAPI MapViewOfFile(
__in HANDLE hFileMappingObject,
__in DWORD dwDesiredAccess,
__in DWORD dwFileOffsetHigh,
__in DWORD dwFileOffsetLow,
__in SIZE_T dwNumberOfBytesToMap
);
返回值为LPVOID,定义为:
LPVOID
A pointer to any type.
This type is declared in WinDef.h as follows:
typedef void *LPVOID;
好的...所以我猜这是 IntPtr
或 UIntPtr
。这article有一个表并建议 LPVOID 应该映射到 IntPtr 或 UIntPtr。好的。
接下来,处理。
HANDLE
A handle to an object.
This type is declared in WinNT.h as follows:
typedef PVOID HANDLE;
好的,HANDLE 是一个 PVOID。
PVOID
A pointer to any type.
This type is declared in WinNT.h as follows:
typedef void *PVOID;
嗯嗯,听起来像 IntPtr
接下来,双字节
DWORD
A 32-bit unsigned integer. The range is 0 through 4294967295 decimal.
This type is declared in WinDef.h as follows:
typedef unsigned long DWORD;
好的,unsigned long 0 到 4294967295,所以这是一个 uint
而 here它建议使用 Int32 或 UInt32。 Int32 将无法存储超过 2,147,483,648 的任何值。所以那个表很可疑。
最后,我们有 SIZE_T,它被定义为一个 ULONG_PTR,它可以是 32 位或 64 位有符号长,具体取决于平台(下面的定义)。这article (和 follow up )得出结论,您应该使用 IntPtr,因为它将处理可变大小。
SIZE_T
The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer.
This type is declared in BaseTsd.h as follows:
typedef ULONG_PTR SIZE_T;
ULONG_PTR
An unsigned LONG_PTR.
This type is declared in BaseTsd.h as follows:
#if defined(_WIN64) typedef unsigned __int64 ULONG_PTR; #else typedef unsigned long ULONG_PTR; #endif
LONG
A 32-bit signed integer. The range is –2147483648 through 2147483647 decimal.
This type is declared in WinNT.h as follows:
typedef long LONG;
INT64
A 64-bit signed integer. The range is –9223372036854775808 through 9223372036854775807 decimal.
This type is declared in BaseTsd.h as follows:
typedef signed __int64 INT64;
因此,虽然我可以查找每个 Windows 数据类型的定义,然后根据大小、符号以及它是否适用于 x86 和 x64 找到相应的 .NET 数据类型,但这并不理想。
是否有明确的引用资料(不是 pinvoke.net)以及 x64 的最新映射表?
最佳答案
将 native 数据类型映射到托管类型时,重要的是大小和一致性。
有符号和无符号类型的选择仅在解释托管值时才重要。
它们都被编码为原始位。
在大多数情况下,您只是将值从一种 API 方法传递到另一种方法;在这些情况下,类型是有符号还是无符号都无关紧要,只要大小合适即可。
因此,一般规则是任何指针大小的值都变成IntPtr
,DWORD
和QWORD
变成U?Int32
和 U?Int64
。
关于c# - 是否有跨平台(x86 和 x64)PInvoke 和 windows 数据类型的权威指南?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9305023/