本主题描述了可用于使应用程序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 | 英特尔安腾平台 |
_M_IX86 | x86平台 |
_M_X64 | x64平台 |
_M_ARM64 | ARM64平台 |
除了特定于体系结构的代码之外,请不要使用这些宏,而是尽可能使用_WIN64,_WIN32和_WIN16。
助手函数
以下内联函数(在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符号扩展int值,UIntToPtr零扩展unsigned int值,LongToPtr符号扩展long值,ULongToPtr零扩展unsigned long值。
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:不是操作员。例如,“〜”:将“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构建应用程序时,调用这些库的代码将不会链接。
原文链接:The Tools