我最近的大部分编程都是使用C / C ++ / C#/ VB6在32位Windows上进行的。最近,我的客户询问我的代码是否可以在64位Windows上运行。
我想知道我可能会在64位Windows上使用哪些遗留功能?我需要考虑和担心的一些现实问题是什么?
显然,我将在64位操作系统上测试我的代码,但我想知道要寻找的常见问题。我更关心现有的二进制文件,但我很乐意在重新编译时(如果可能的话)担心会有什么问题。
编辑:这是64位移植错误的nice list。
答案 0 :(得分:22)
就我而言,将C / C ++代码移植到64位Windows的最重要的事情是在启用MEM_TOP_DOWN
分配的情况下测试您的应用程序(AllocationPreference
注册表价值,如4-Gigabyte Tuning:
要强制分配在较低地址之前从较高地址分配以进行测试,请在调用
MEM_TOP_DOWN
时指定VirtualAlloc
或将以下注册表值设置为0x100000:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference
什么时候重要?
/LARGEADDRESSAWARE
MSVC链接器选项构建的(或者通过其他方式在其PE头中设置了IMAGE_FILE_LARGE_ADDRESS_AWARE
标志,例如{{1}然后,他们在64位Windows中获得了完整的4 GB虚拟地址空间,您必须使用editbin.exe
注册表值设置它们进行测试。AllocationPreference
注册表值设置来测试它们。AllocationPreference
注册表值进行测试。如果您的C / C ++应用程序属于这三个类别中的一个并且您没有使用AllocationPreference
分配进行测试,则测试不太可能捕获代码中的任何指针截断/签名错误。
第二个最重要的事情,如果您使用MSVC并且要重新编译64位的C / C ++代码,那么使用 64位的MEM_TOP_DOWN
编译器选项 build :
/Wp64
或C样式转换),以及其他一些64位移植问题。reinterpret_cast
进行编译,而应使用针对64位平台的编译器,但仅在编译时不会捕获指针截断/扩展问题。使用针对64位和的编译器为64位构建启用/Wp64
编译器选项将在编译时捕获许多指针截断/扩展问题,这将节省您的时间从长远来看。/Wp64
选项。我可以看到为什么该选项不适用于32位版本(这是一个需要注释你的许多typedef的邪恶黑客),但不幸的是它也被弃用于64位版本(它实际上很有用)。 答案 1 :(得分:15)
文章:
20 issues of porting C++ code on the 64-bit platform
The forgotten problems of 64-bit programs development
64 bits, Wp64, Visual Studio 2008, Viva64 and all the rest...
Traps detection during migration of C and C++ code to 64-bit Windows
和
Viva64工具 - 用于检查64位程序:
答案 2 :(得分:5)
如果您拥有100%“类型安全的托管代码”,那么迁移.NET代码可能会更容易。 您只需将其复制到64位平台并在64位CLR下成功运行即可。 关于将32位托管代码迁移到64位,请检查此MSDN link。
Btw,hanselman blogged最近关于这个话题。
答案 3 :(得分:3)
如果您正在谈论32位程序,那么几乎没有什么可担心的,因为Windows 64将在模拟下以32位运行它们。未来Windows版本(例如Windows 7)的任何问题都可能是不兼容的,而不是64位操作系统的问题。
但是,如果您的托管代码是为“任何CPU”目标平台编译的,并且您调用非托管代码(例如PInvoke),或者依赖于其他程序集,则需要注意一些事项。 Scott Hanselman关于x86 / x64 CLR的post涵盖了这一点,并且很好地解释了Win32 / 64上的CLR。
在开发64位本机程序时,Programming Guide for 64-bit Windows是一个很好的指南。它主要归结为指针和数据类型的大小:)
答案 4 :(得分:2)
32位程序将在64位窗口上正常运行。只要你没有做任何设备驱动程序的开发当然。
如果您是第一次将软件编译为64位软件,则需要注意以下事项:
答案 5 :(得分:1)
如果因任何原因进行DLL注入,则会遇到麻烦。
答案 6 :(得分:0)
从C / C ++的角度来看......
一个显而易见的事情是int的大小将变为8个字节而不是4个字节。如果您的任何代码依赖于您,您可能会得到意想不到的结果。结构和变量对齐可能会发生变化。您可以使用#pragma pack克服它,但我对齐和包装不是很流畅。
如果你使用任何包含int的联合,行为可能会改变。
如果使用任何位域结构,基于整数,额外的32位可能会引起混淆。符号位不会是您认为的位置。
如果您编码任何十六进制常量并且预期符号会变为负数,则可能会出现问题。例 0x8000000是一个负数作为日志,或32位整数。在64位平台上作为整数的0x80000000是正数。直接设置符号位,你必须使用0x80000000 00000000(嵌入空间只是为了可读性)
此外,我希望size__t适当增长。如果您根据MAX_INT进行任何分配,它们会更大。
为了避免这些类型的异常,我通常坚持使用long而不是整数。
答案 7 :(得分:0)
32位仿真真的是防弹吗?我已经看到注册表的布局略有不同。我只是想知道什么是典型的东西不起作用......
此外,C:\ windows \ SYSTEM32目录只能包含64位DLL。如果您有32位DLL,则需要将其放在C:\ windows \ syswow64 \
中