是否有一个明确的指导,以跨平台(x86和x64)的PInvoke和Windows数据类型? [英] Is there a definitive guide to cross platform (x86 and x64) PInvoke and windows data types?

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

问题描述

我核实了一些code用于基于x64的兼容性。 previously我用PInvoke.net,但我已经找到了一些犯罪嫌疑人的声明在64位方面。所以,现在,我:

  1. 查找了API参考等的 MapViewOfFile
  2. 中查找窗口的数据类型定义
  3. 找到相应的.NET类型。

这是第3步,我想一个明确的参考

作为一个例子:

  LPVOID WINAPI MapViewOfFile(
  一切变得HANDLE hFileMappingObject,
  一切变得DWORD dwDesiredAccess,
  一切变得DWORD dwFileOffsetHigh,
  一切变得DWORD dwFileOffsetLow,
  一切变得SIZE_T dwNumberOfBytesToMap
);
 

返回值是LPVOID,其被定义为:

  

LPVOID

     

一个指向任何类型的。

     

这类型在WINDEF.H声明如下:

 的typedef无效* LPVOID;
 

行...所以我想这是的IntPtr UIntPtr 。 有一个表,并建议该文章LPVOID应该映射到的IntPtr或UIntPtr。确定。

接下来,处理。

  

HANDLE

     

一个对象句柄。

     

这类型在WINNT.H声明如下:

     

的typedef PVOID HANDLE;

确定,句柄是一个PVOID。

  

PVOID

     

一个指向任何类型的。

     

这类型在WINNT.H声明如下:

     

的typedef无效* PVOID;

Hmmmm,听起来像是的IntPtr

接下来,DWORD

  

DWORD

     

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

     

这类型在WINDEF.H声明如下:

 的typedef无符号长DWORD;
 

确定,无符号长0至4294967295,所以这是一个尚未 UINT 此处它表明的Int32或UInt32的。的Int32将不能存储任何值超过2147483648。因此,该表​​是非常可疑的。

最后,我们SIZE_T,其被定义为一个ULONG_PTR其可以是32或64位有符号长取决于平台(定义如下)。这文章(和的跟进)的结论,你应该使用IntPtr的,因为它会处理该变量的大小。

  

SIZE_T

     

字节向其中一个指针可以指向的最大数量。使用了   算上必须跨越的全部范围内的指针。

     

这类型在BaseTsd.h声明如下:

 的typedef ULONG_PTR SIZE_T;
 

     

ULONG_PTR

     

这是无符号LONG_PTR。

     

这类型在BaseTsd.h声明如下:

 #如果定义(_WIN64)
 无符号的typedef __int64 ULONG_PTR;
#其他
 的typedef无符号长ULONG_PTR;
#ENDIF
 

     

     

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

     

这类型在WINNT.H声明如下:

 的typedef久长;
 

     

INT64

     

一个64位有符号整数。的范围是-9223372036854775808通过   9223372036854775807十进制。

     

这类型在BaseTsd.h声明如下:

 的typedef签署__int64 INT64;
 

所以,虽然我可以看一下每一个窗口的数据类型的定义,然后找到在规模,签署条款相应的.NET数据类型,以及它是否适用于x86和x64的,它的效果并不理想。

有一个明确的参考那里(没有pinvoke.net)具有良好的映射表,这是最新的64?

解决方案

在本机映射到数据类型托管类型,所有重要的是规模性和一致性。

签署与无符号类型的选择只有事宜时,除preting的管理价值。
他们俩都是编组为原料位。

在大多数情况下,你将只是从一个API方法将值传递给他人;在这些情况下,无所谓的类型是否带符号,只要它是正确的大小。

因此​​,一般的规则是,任何指针大小的值变的IntPtr DWORD QWORD 成为 U的?的Int32 U&Int64的,分别为。

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. Look up the API reference such as MapViewOfFile
  2. Look up the windows data type definition
  3. Find the corresponding .NET type.

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

As an example:

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

Return value is LPVOID, which is defined as:

LPVOID

A pointer to any type.

This type is declared in WinDef.h as follows:

typedef void *LPVOID;

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

Next, HANDLE.

HANDLE

A handle to an object.

This type is declared in WinNT.h as follows:

typedef PVOID HANDLE;

OK, HANDLE is a PVOID.

PVOID

A pointer to any type.

This type is declared in WinNT.h as follows:

typedef void *PVOID;

Hmmmm, sounds like IntPtr

Next, DWORD

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;

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.

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.

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;

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.

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.

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.

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天全站免登陆