繁体   English   中英

将 32 位应用程序转换为 C 中的 64 位应用程序

[英]Converting 32-bit Application Into 64-bit Application in C

我目前正在将 32 位应用程序转换为 C 中的 64 位应用程序。该应用程序目前正在 x86 架构(Windows、osx、Unix、Linux)上工作。 因此,在开始编码之前,我想知道在转换应用程序时需要考虑什么。

  1. 找出是谁写的。 他们是白痴吗? 他们是从几年前? 你能问他们问题吗? 他们是否熟悉多个平台和系统的存在? 了解程序作者的心态将有助于您在遇到问题时理解问题。
  2. 启动并运行 64 位机器/构建环境。
  3. 用 int 替换 long。 非常清楚LONG并不long
  4. intptr_t替换(int)&x转换和输入,用uintptr_t替换(int)&x (unsigned int)&x
  5. 审计任何依赖于将结构转换为char*以对其进行指针运算的内容。
  6. 正则表达式搜索 \\<4\\> 以防您假设4 = sizeof(void*)
  7. 要有耐心。 当你发现问题时,如果存在同样的问题,就去别处寻找,并将解决方案包装在一个宏中。
  8. 尽量不要使用#ifdef RUN64或任何类似的东西。 如果 128 位平台开始流行,您会后悔的。
  9. 将所有更改封装在一些集中式宏中,这些宏将隐藏程序中其他地方的可移植性差异。
  10. 使用覆盖测试人员来帮助确保您已覆盖所有内容(如果适用)

编辑根据评论的建议添加了uintptr_t注释。

一个尚未提及的潜在问题是,如果您的应用程序从磁盘读取或写入二进制数据(例如,使用fread读取结构数组),您将必须非常仔细地检查,并且可能最终有两个读取器:一个用于遗留文件和 64 位文件之一。 或者,如果您小心地使用<stdint.h>头文件中的uint32_t等类型,您可以重新定义结构以使其兼容。 在任何情况下,二进制 I/O都是需要注意的。

这实际上取决于应用程序及其编码方式。 某些代码可以使用 64 位编译器重新编译,它就可以正常工作,但通常只有在代码设计时考虑了可移植性时才会发生这种情况。

如果代码对本机类型和指针的大小有很多假设,如果它有很多位打包技巧,或者它使用字节指定的协议与外部进程对话,但使用一些关于本机类型大小的假设,那么它可能需要一些或大量的工作才能获得干净的编译。

几乎每个强制转换和编译器警告都是一个需要检查的危险信号。 如果代码开始时不是“警告干净”,那么这也表明可能需要进行大量工作。

如果您为您的值使用了正确的类型 - 例如。 size_tptrdiff_tuintptr_t ,在适当的情况下来自stdint.h的固定大小的 int 类型 - 并且没有对值大小进行硬编码,您的代码应该开箱即用。

切换到 64 位时面临的主要问题是指针的大小不同(64 位而不是 32 - duh)整数的大小和 long 的大小也可能不同,具体取决于平台。

为什么这是个问题? 好吧,事实并非如此,除非您的代码假定 sizeof(int) == sizeof(void*)。 这可能会导致讨厌的指针错误。

嗯,从根本上说,更改的数量相当少,但是如果应用程序没有精心编写以使其具有某种程度的可移植性,这仍然是一项主要任务。

主要区别在于指针是 64 位宽,大多数其他数据类型没有改变。 int 仍然是 32 位,而 long 可能也仍然是 32 位。 因此,如果您的代码在整数和指针之间进行转换,那将会中断。 类似地,任何依赖于成员的特定偏移量的结构或类似结构都可能会中断,因为其他成员现在可能更大,因此更改偏移量。

当然,你的代码一开始就不应该依赖这些技巧,所以在理想的世界里,这根本不是问题,你可以简单地重新编译,一切都会好起来的。 但你可能并不生活在一个理想的世界...... ;)

C 中 32 位和 64 位编程之间的两个主要区别是sizeof(void*)sizeof(long) 您将遇到的主要问题是大多数 Unix 系统使用 I32LP64 标准,该标准定义了 64 位,而 Win64 使用 IL32LLP64 标准,该标准定义了 32 位。 如果您需要支持跨平台编译,您可能希望对 32 位和 64 位整数使用一组基于架构的 typedef,以确保所有代码的行为一致。 这是作为 C99 标准的一部分作为 stdint.h 的一部分提供的。 如果您不使用 C99 编译器,则可能需要滚动自己的等效项

正如其他地方所述,转换的主要问题是假定sizeof(int) == sizeof(long) == sizeof(void*)代码、支持已写入磁盘的数据的代码和跨平台 IPC 的代码。

要详细了解这背后的历史,请查看 ACM Queue 中的这篇文章

已经有很多好的答案了。

考虑使用Gimpel Lint 它可以准确指出有问题的构造类型。 如果您的经历和我一样,它还会向您展示系统中与 32/64 位端口无关的许多错误。

所有关于开发人员的64位:

有关64位开发的文章

链接集合64位资源

工具Viva64

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM