是否有跨平台(x86 和 x64)PInvoke 和 Windows 数据类型的权威指南? [英] Is there a definitive guide to cross platform (x86 and x64) PInvoke and windows data types?

查看:24
本文介绍了是否有跨平台(x86 和 x64)PInvoke 和 Windows 数据类型的权威指南?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在验证 x64 兼容性的一些代码.以前我使用过 PInvoke.net,但我发现了一些关于 x64 的可疑声明.所以现在,我:

I am verifying some code for x64 compatability. Previously I've used PInvoke.net, but I've found a few suspect declarations in terms of x64. So now, I:

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

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

It's step 3 where I'd like a definitive reference

举个例子:

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

返回值为LPVOID,定义为:

Return value is LPVOID, which is defined as:

LPVOID

指向任何类型的指针.

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

This type is declared in WinDef.h as follows:

typedef void *LPVOID;

好的...所以我猜是 IntPtrUIntPtr.这篇文章有一个表格并建议LPVOID 应该映射到 IntPtr 或 UIntPtr.好的.

OK... so I guess that's IntPtr or UIntPtr. This article has a table and suggests LPVOID should map to IntPtr or UIntPtr. OK.

接下来,处理.

句柄

对象的句柄.

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

This type is declared in WinNT.h as follows:

typedef PVOID 句柄;

typedef PVOID HANDLE;

好的,HANDLE 是一个 PVOID.

OK, HANDLE is a PVOID.

PVOID

指向任何类型的指针.

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

This type is declared in WinNT.h as follows:

typedef void *PVOID;

typedef void *PVOID;

嗯,听起来像 IntPtr

接下来,双字

双字

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

A 32-bit unsigned integer. The range is 0 through 4294967295 decimal.

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

This type is declared in WinDef.h as follows:

typedef unsigned long DWORD;

好的,unsigned long 0 到 4294967295,所以这是一个 uint此处 建议使用 Int32 或 UInt32.Int32 将无法存储超过 2,147,483,648 的任何值.所以这张表很可疑.

OK, unsigned long 0 to 4294967295, so that's a uint and yet here it suggests Int32 or UInt32. Int32 won't be able to store any value over 2,147,483,648. So that table is very suspect.

最后,我们有 SIZE_T,它被定义为 ULONG_PTR,它可以是 32 位或 64 位有符号长,具体取决于平台(定义如下).此文章(和跟进) 得出结论,您应该使用 IntPtr,因为它将处理可变大小.

Finally, we have SIZE_T, which is defined as a ULONG_PTR which can be 32 or 64 bit signed long depending on the platform (definitions below). This article (and follow up) conclude you should use IntPtr, since it will handle the variable sizes.

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.

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

This type is declared in BaseTsd.h as follows:

typedef ULONG_PTR SIZE_T;

ULONG_PTR

一个未签名的 LONG_PTR.

An unsigned LONG_PTR.

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

This type is declared in BaseTsd.h as follows:

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

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

A 32-bit signed integer. The range is –2147483648 through 2147483647 decimal.

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

This type is declared in WinNT.h as follows:

typedef long LONG;

INT64

一个 64 位有符号整数.范围是 –9223372036854775808 到9223372036854775807 十进制.

A 64-bit signed integer. The range is –9223372036854775808 through 9223372036854775807 decimal.

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

This type is declared in BaseTsd.h as follows:

typedef signed __int64 INT64;

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

So, while I can look up the definition of every windows data type and then find a corresponding .NET datatype in terms of size, sign, and whether it works on both x86 and x64, it's not ideal.

是否有明确的参考文献(不是 pinvoke.net)以及适用于 x64 的最新映射表?

Is there a definitive reference out there (not pinvoke.net) with a good mapping table that's up to date for x64?

推荐答案

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

When mapping native datatypes to managed types, all that matters is size and consistency.

有符号类型与无符号类型的选择仅在解释托管值时才重要.
它们都被编组为原始位.

The choice of signed vs. unsigned types only matters when interpreting the managed value.
They're both marshaled as raw bits.

在大多数情况下,您只是将值从一种 API 方法传递到另一种方法;在这些情况下,类型是有符号的还是无符号的并不重要,只要大小合适即可.

In most cases, you will just be passing values from one API method to another; in these cases, it doesn't matter whether the type is signed or unsigned, as long as it's the right size.

因此,一般规则是任何指针大小的值都变成IntPtr,而DWORDQWORD变成U?Int32U?Int64,分别.

Therefore, the general rule is that any pointer-sized value becomes IntPtr, and DWORD and QWORD become U?Int32 and U?Int64, respectively.

这篇关于是否有跨平台(x86 和 x64)PInvoke 和 Windows 数据类型的权威指南?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆