工具

本主题介绍可用于使应用程序 64 位就绪的工具。 Windows 10适用于基于 x64 和 ARM64 的处理器。

包含文件

在 32 位和 64 位 Windows 之间,API 元素几乎完全相同。 Windows 头文件已修改,以便可用于 32 位和 64 位代码。 新的 64 位类型和宏在新的头文件 Basetsd.h 中定义,该文件位于 Windows.h 包含的头文件中。 Basetsd.h 包括新的数据类型定义,以帮助使源代码的字大小独立。

新数据类型

Windows 头文件包含新的数据类型。 这些类型主要用于与 32 位数据类型的类型兼容性。 新类型提供与现有类型完全相同的类型,同时支持 64 位 Windows。 有关详细信息,请参阅 新数据类型 或 Basetsd.h 头文件。

预定义的宏

编译器定义以下宏来标识平台。

含义
_WIN64 64 位平台。 这包括 x64 和 ARM64。
_WIN32 32 位平台。 此值也由 64 位编译器定义,以实现向后兼容性。
_WIN16 16 位平台

以下宏特定于体系结构。

含义
_M_IA64 Intel Itanium 平台
_M_IX86 x86 平台
_M_X64 x64 平台
_M_ARM64 ARM64 平台

请勿使用这些宏,除非与特定于体系结构的代码一起使用,而应尽可能使用 _WIN64、_WIN32 和 _WIN16。

Helper 函数

Basetsd.h) 中定义的以下内联函数 (有助于安全地将值从一种类型转换为另一种类型。

void            * Handle64ToHandle( const void * POINTER_64 h ) 
void * POINTER_64 HandleToHandle64( const void *h )
long              HandleToLong(     const void *h )
unsigned long     HandleToUlong(    const void *h )
void            * IntToPtr(         const int i )
void            * LongToHandle(     const long h )
void            * LongToPtr(        const long l )
void            * Ptr64ToPtr(       const void * POINTER_64 p )
int               PtrToInt(         const void *p )
long              PtrToLong(        const void *p )
void * POINTER_64 PtrToPtr64(       const void *p )
short             PtrToShort(       const void *p )
unsigned int      PtrToUint(        const void *p )
unsigned long     PtrToUlong(       const void *p )
unsigned short    PtrToUshort(      const void *p )
void            * UIntToPtr(        const unsigned int ui )
void            * ULongToPtr(       const unsigned long ul )

警告

IntToPtr sign-extend the int value, UIntToPtr zero extend the unsigned int value, LongToPtr sign-extend the long value, ULongToPtr zero- extend the unsigned long value.

64 位编译器

64 位编译器可用于识别指针截断、类型转换不正确和其他 64 位特定问题。

首次运行编译器时,可能会生成许多指针截断或类型不匹配警告,如下所示:

warning C4311: 'type cast' : pointer truncation from 'unsigned char *' to 'unsigned long '

使用这些警告作为指导,使代码更可靠。 最好消除所有警告,尤其是指针截断警告。

64 位编译器开关和警告

请注意,此编译器启用 LLP64 数据模型。

有一个警告选项可帮助移植到 LLP64。 -Wp64 -W3 开关启用以下警告:

  • C4305:截断警告。 例如,“return”:从“unsigned int64”到“long”的截断。
  • C4311:截断警告。 例如,“type cast”:从“int*_ptr64”到“int”的指针截断。
  • C4312:转换为较大大小的警告。 例如,“type cast”:从“int”转换为“int*_ptr64”,其大小更大。
  • C4318:传递零长度。 例如,将常量零作为长度传递给 memset 函数。
  • C4319:Not 运算符。 例如,“~”:将“unsigned long”扩展到更大的“unsigned _int64”的零。
  • C4313:调用具有冲突的转换类型说明符和参数的 printf 函数系列。 例如,格式字符串中的“printf”: “%p”与类型为“_int64”的参数 2 冲突。另一个示例是调用 printf (“%x”,pointer_value) ;这会导致截断上限 32 位。 正确的调用是 printf (“%p”,pointer_value) 。
  • C4244:与现有警告 C4242 相同。 例如,“return”:从“_int64”转换为“unsigned int”,可能会丢失数据。

64 位链接器和库

若要生成应用程序,请使用 Windows SDK 提供的链接器和库。 大多数 32 位库都有相应的 64 位版本,但某些旧库仅在 32 位版本中可用。 为 64 位 Windows 生成应用程序时,调用这些库的代码将不会链接。