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:
- Look up the API reference such as MapViewOfFile
- Look up the windows data type definition
- 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?