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

标签 c# c++ winapi 64-bit pinvoke

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

  1. 查找 API 引用,例如 MapViewOfFile
  2. 查找 windows data type定义
  3. 找到相应的 .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;

好的...所以我猜这是 IntPtrUIntPtr。这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,所以这是一个 uinthere它建议使用 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 方法传递到另一种方法;在这些情况下,类型是有符号还是无符号都无关紧要,只要大小合适即可。

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

关于c# - 是否有跨平台(x86 和 x64)PInvoke 和 windows 数据类型的权威指南?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9305023/

相关文章:

c++ - Vim + OmniCppComplete : Completing on Class Members which are STL containers

c++ - 无法将我的对象推送到 std::vector - gcc 找不到类似复制构造的东西

unix - 经验丰富的 Unix 程序员使用 Microsoft 工具应该注意什么?

C#如何获取正在设置的属性的名称

c# - 需要我已经拥有的 Objective-C 版本的 Java 加密和 Base 64 编码

c++ - 如何将 vector 传递给基于推力的 odeint 观察器的构造函数,以便可以在仿函数中读取它

c++ - 我应该使用什么来代替 AddPort?

从 QueryPerformanceCounter() 计算周期/字节

c# - OracleConnectionPoolManager 在其终结器中抛出异常

c# - 如何以编程方式更新和保存 app.config 应用程序设置