Windows 64 位版本的C/C++编程
来源:互联网 发布:一口气英语软件下载 编辑:程序博客网 时间:2024/05/01 03:17
/WP64:使编译器警告您潜在的问题
Microsoft_ Visual C 和 Microsoft_ Visual C++_ .NET 2002 编译器添加了 /WP64 开关,这使您可以测试 32 位代码的 64 位兼容性问题。编译器将发出有关指针截断和不正确转换的警告。将 32 位应用程序迁移到 Windows 64 位版本中前面的一个步骤就是打开这个标记,然后就像通常编译代码那样来编译您的代码。第一次会有几个错误。例如,请看下面这个代码片段:
DWORD i = 0;size_t x = 100;i = x; // C4267: warning C4267: '=' : conversion from // 'size_t' to 'DWORD', possible loss of data.
在 32 位的平台上,这段代码能够很好的进行编译,因为 size_t 是 32 位的,但是在 64 位的平台上,size_t 就是 64 位的整数。启用 /WP64 后,编译器将会警告您类似的情况。
其他示例:
void func(DWORD context){ char* sz = (char*)context; // C4312: warning C4312: // 'type cast' : conversion // from 'DWORD' to 'char *' of // greater size // Do something with sz..}char* string = "the quick brown fox jumped over the lazy dog.";func((DWORD)string); // C4311: warning C4311: 'type cast' : // pointer truncation from 'char *' // to 'DWORD'
在修复这些错误后,请测试您的 32 位代码。您希望确保 32 位的代码继续按预期那样工作。32 位和 64 位二进制文件应该从相同的代码库中构建。这就是编写不断前进的 Windows 应用程序的关键概念。开始时,您需要考虑 32 位和 64 位的问题,并且为应用程序编写可以运行在这两个平台上的代码。
新的数据类型
Windows 64 位版本使用 LLP64 数据模型。这意味着标准 C 类型 int 和 long 保持为 32 位整数。数据类型 size_t 将映射到处理器词大小(IA32 为 32 位,IA64 为 64 位),并且__int64 是 64 位整数。在协助迁移 32 位代码时就会完成上述操作。意义在于您可以对应用程序的 32 位版本和 64 版本使用相同的代码库。
还有一个称为 LP64 的数据模型,它将标准的 C 类型 long 映射到 64 位整数,并使 int 保持为 32 位的整数。这种数据模型常见于 Unix 平台,但从单个代码库同时创建应用程序的 32 位和 64 位版本时可能有一些困难。您可能注意到了此处的常见主题。32 位平台与 64 位平台的思想就是应该能够从单个代码库中构建两个版本的应用程序。如果无法做到,那么您可能要重新审视您的设计。具有单个代码库就是巨大的胜利,尤其是如果您计划发行两个版本。
多态类型
由于 Win32 API 是针对 C 的,在很多情况下,您都需要将整数转换成指针或者相反。在 32 位的硬件上不会有问题,其中指针的大小和整数的大小是相同的,但在 64 位的硬件上却完全不一样。这就是多态类型出现的原因。
对于特定的精度,您可以使用固定精度的数据类型。不管处理器的词大小如何,它们的大小都是一致的。大多数这些类型都在它们的名称中包含精度,可以从下面的表中看出:
表 1. 固定精度的数据类型类型定义DWORD32
32 位无符号整数
DWORD64
64 位无符号整数
INT32
32 位有符号整数
INT64
64 位有符号整数
LONG32
32 位有符号整数
LONG64
64 位有符号整数
UINT32
无符号 INT32
UINT64
无符号 INT64
ULONG32
无符号 LONG32
ULONG64
无符号 LONG64
此外,当您需要数据类型的精度随着处理器词大小变化时,请使用指针精度数据类型。这些类型又称为“多态”数据类型。这些类型通常以 _PTR 后缀结尾,如下面的表格所示:
表 2. 指针精度的数据类型类型定义DWORD_PTR
指针精度的无符号长类型
HALF_PTR
指针大小的一半。用于包含一个指针和两个小型字段的结构中
INT_PTR
指针精度的有符号整型
LONG_PTR
指针精度的有符号长类型
SIZE_T
指针可以引用的最大字节数。用于必须跨指针的整个范围的计数
SSIZE_T
有符号 SIZE_T
UHALF_PTR
无符号 HALF_PTR
UINT_PTR
无符号 INT_PTR
ULONG_PTR
无符号 LONG_PTR
LPARAM
与 LONG_PTR 为同义词,(在WTypes.h 中定义)
WPARAM
与 UINT_PTR 为同义词,(在 WTypes.h 中定义)
通过整数参数传递参数或上下文信息的所有 Win32 API 都更改为使用这些新的类型。SetWindowLong 和 SetWindowLongPtr 函数都是很好的示例:
旧方法:
LONG SetWindowLong( HWND hWnd, int nIndex, LONG dwNewLong);
新的多态方法:
LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong);
请注意,该函数的 xxxPtr 版本使用新的多态类型。对于开发人员而言,通过在窗口的额外数据区域中存储指针来存储窗口的上下文信息是相当常见的。使用 SetWindowLong 函数在 Windows 32 位版本上存储指针的任何代码必须更改为调用 SetWindowLongPtr。该更改非常简单并且很快就可以完成,因为大多数更改要求使用多态类型。
另外,WindowProc 和 GetQueuedCompletionStatus 也是很好的示例:
LRESULT CALLBACK WindowProc( HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);BOOL GetQueuedCompletionStatus( HANDLE hCompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletionKey, LPOVERLAPPED* lpOverlapped, DWORD dwMilliseconds);
WindowProc 使用 LPARAM,后者是多态类型。GetQueuedCompletionStatus 使用 ULONG_PTR,后者也是多态类型。这使那些假设整数的大小与指针大小相同的现有代码可以在进行很少修改的情况下继续工作。
编译器的新优化模式:PoGO 和 LTCG
包括 Microsoft_ Visual Studio_ .NET 2002 的编译器包含两个新的优化模式:Link Time Code Generation(LTCG,又称 Whole Program Optimization)和 Profile Guided Optimization (PoGO)。代码优化在 Itanium 处理器上比在 x86 平台上更为重要,因为编译器对生产高效代码负有全部责任。这两种优化模式将增加构建次数,并且要求良好的测试方案,尤其是 PoGO(因为它需要捕获分析数据)。LTCG 允许链接器跨模块边界执行优化,并且通过生成更好的内嵌代码甚至使用自定义调用约定,在链接阶段实际地生成代码以产生更有效的二进制文件。PoGO 使编译器可以根据使用模式来进行优化。它要求两个阶段的构建过程。在第一个阶段中,二进制文件用于使它收集分析数据。在第二个阶段中,对分析数据进行分析后,数据用于指导优化。
杂项性能
当前的编译器擅长于产生高优化的代码。在 Itanium 处理器上,编译器负责非常多的工作。因为 Itanium 是顺序处理器,编译器必须执行优化(如重新排列指令),以便它们可以并行执行。同样,借助于增加的谓词寄存器,编译器在优化分支处理上有了更多的自由。使用谓词寄存器,编译器可以完全去除一个分支,并可以使用指令的谓词字段来控制是否实际地执行某个指令。这对于性能是有好处的,因为不在小块的代码上跳转以及不再使指令预取无效,编译器可以通知处理器有条件地忽略这些指令。
校准
考虑 Itanium 处理器上的校准非常重要。指针必须在 64 位边界上校准,否则您将收到一个校准异常。您可以使用 UNALIGNED 关键字来允许未校准的指针差异,但您将为此付出巨大的性能代价。通常情况下,可以使用 #pragma pack 指令,让编译器处理结构的校准。这使您可以指定用于 32 位和 64 位的不同的校准(在编译时),而不是手动校准代码中的结构。
- Windows 64 位版本的C/C++编程
- Windows 64 位版本的C/C++编程
- Windows 64 位版本的C/C++编程
- 64位与32位编程的数据类型区别(C/C++) (主要介绍windows)
- windows 64位技术--C/C++的64位移植
- windows 64位技术--C/C++的64位移植
- 基于64位Windows 10系统的C语言与MATLAB混合编程
- 编程禁止Windows文件保护[c版本]
- [C/C++]_[初级]_[获取Windows系统的位数32位或64位]
- 64位与32位编程的数据类型区别(C/C++)
- 64位与32位编程的数据类型区别(C/C++)
- 64位与32位编程的数据类型区别(C/C++)
- 64位与32位编程的数据类型区别(C/C++)
- 32位的C语言编程环境
- C/C++ 开发人员采用 Windows 64 位
- C++Builder 生成64位Windows应用
- 64位windows上访问64位oracle 12c
- 在Windows下测试CPU是32位还是64位的C代码
- 对自己新的认知
- C++入门教程 之 初学者,你应当如何学习C++以及编程
- POJ 动态规划 题集
- 更快、更强 64位编程
- Windows上64位编程
- Windows 64 位版本的C/C++编程
- 内存管理
- 本博增加 Xtreme ToolkitPro v15.2.1 分类说明
- Codeforces 160D Edges in MST
- spring与hibernate整合之:继承HibernateDAOSupport方式+理解xml与AutoWired、Resource的区别
- 64位windows常规编程简介
- uva 147 Dollars
- shell 中的括号(小括号,花括号)
- xetex多字体测试