我们有一个 32 位 Windows 应用程序,它使用 C++ 和良好的旧 Windows 应用程序模型。从技术上讲,是否可以通过转动编译器开关或使用一些宏来将其编译为 32 位和 64 位?
目前我认为代码不会编译为 64 位应用程序,我将不得不修复编译错误,一般来说我应该如何进行以便它编译为 64 位和 32 位应用程序。我应该记住什么?将面临哪些挑战?任何意见和提示将不胜感激。谢谢
我们有一个 32 位 Windows 应用程序,它使用 C++ 和良好的旧 Windows 应用程序模型。从技术上讲,是否可以通过转动编译器开关或使用一些宏来将其编译为 32 位和 64 位?
目前我认为代码不会编译为 64 位应用程序,我将不得不修复编译错误,一般来说我应该如何进行以便它编译为 64 位和 32 位应用程序。我应该记住什么?将面临哪些挑战?任何意见和提示将不胜感激。谢谢
编译器根据其目标平台定义宏。例如,GCC 定义__i386__
and __amd64__
,MSVC分别为 32 位和 64 位定义_M_IX86
and 。_M_X64
例如,您可以在预处理器#ifdef
语句中使用这些宏来指导编译流程。
对于不同的编译器,有一个关于预定义 C/C++ 编译器宏的优秀资源。
关于“我应该记住什么?会有什么挑战? ”这些是我在将代码从 32 位移植到 64 位时遇到的最常见问题:
确保在编译时使用最严格的警告级别(/W4
在 microsoft 的编译器或-Wall -Wextra -pedantic-errors
gcc 上)以帮助捕获从较大类型到较小类型的转换。
这是 Microsoft 的移植指南,但也适用于其他编译器。
这当然是可能的,因为我们这样做了。最困难的部分是为 x64 配置 Visual Studio(这并不难)。除此之外,没有什么特别的,至少如果 C++ 是最干净的(即使不是)。完全相同的来源适用于两者。没有条件编译或任何需要。
移植时最大的问题应该是不同类型的 sizeof() 在这里和那里。因此,在 32 位上正确运行的代码片段可能会在 64 位上造成定时炸弹效应。例如,你可以有一些这样的代码:
size_t sz = GetSomethingBig();
DWORD dw = (DWORD)sz;
因此,在 32 位时,size_t 和 DWORD 这两种类型具有相同的大小(4 个字节)。在移植版本中,size_t 将是 8 个字节长,而 DWORD 仍然相同。当我们进行原始 C 风格的类型转换时,不会出现编译错误。在运行时,如果 sz 小于 0x100000000,一切正常。所有其他值都会导致数据丢失,影响难以预测。