工具
本主题介绍可用于使应用程序 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 生成应用程序时,调用这些库的代码将不会链接。