我最近的大部分编程都是在 32 位 Windows 上使用 C/C++/C#/VB6 进行的。 最近,我的客户询问我的代码是否可以在 64 位 Windows 上运行。
我想知道我可能使用的哪些旧功能在 64 位 Windows 上会受到破坏? 我需要思考和担心哪些现实问题?
显然,我将在 64 位操作系统上测试我的代码,但我想知道要查找哪些常见问题。 我更关心现有的二进制文件,但我愿意接受关于重新编译时需要担心的问题(如果可能)的评论。
编辑:这是 64 位移植错误的不错列表。
Most of my recent programming has been on 32-bit Windows using C/C++/C#/VB6 . Lately, my customers are asking if my code will run on 64-bit Windows.
I'm wondering what legacy features I might be using that will break on 64-bit Windows? What are some real-world issues I need to think about and worry about?
Obviously, I will test my code on the 64-bit OS, but I'd like to know what common issues to look for. I more concerned with the existing binaries, but I am open to comments about what to worry about when recompiling (where possible).
EDIT: Here is a nice list of 64-bit porting bugs.
发布评论
评论(8)
32位模拟真的防弹吗? 我发现注册表的布局略有不同。 我只是想知道什么典型的东西不起作用...
此外,C:\windows\SYSTEM32 目录只能包含 64 位 DLL。 如果你有32位DLL,则需要将其放在C:\windows\syswow64\
Is the 32-bit emulation really bullet proof? I have seen that the registry is layed out a little differently. I'm just wondering what typical things don't work...
Also, the C:\windows\SYSTEM32 directory can only contain 64-bit DLLs. If you have a 32-bit DLL, you need to put it in C:\windows\syswow64\
从 C/C++ 的角度来看......
一个明显的事情是 int 的大小将变为 8 字节而不是 4 字节。 如果您的任何代码依赖于此,您可能会得到意外的结果。 结构和变量对齐可能会发生变化。 您也许可以使用 #pragma pack 来克服它,但我在对齐和打包方面不是很流利。
如果您使用任何包含整数的联合,则行为可能会改变。
如果您使用任何基于整数的位域结构,额外的 32 位可能会导致混乱。 符号位不会在您想象的位置。
如果您编写任何十六进制常量并期望符号变为负数,则可能会遇到问题。 例子
0x8000000 是一个对数负数,或 32 位整数。 0x80000000 在 64 位平台上作为整数是正数。 要直接设置符号位,您必须使用 0x80000000 00000000 (仅用于可读性的嵌入空间)
另外,我希望 size__t 能够适当增长。 如果您基于 MAX_INT 进行任何分配,它们将会大得多。
为了避免这些类型的大小异常,我通常坚持使用长整型而不是整型。
From a C/C++ perspective....
One obvious thing is that the size of an int will become 8 bytes instead of 4 bytes. If any of your code is dependent on that you may get unexpected results. Structure and variable alignments may shift. You may be able to overcome it with a #pragma pack, but I am not very fluent in alignments and packing.
If you use any unions with ints in them, the behavior may change.
If you are using any bitfield structures, based on ints the extra 32 bits may cause confusion. The sign bit won't be where you thought it was.
If you code any hex constants and expect signs to go negative, you may have issues. Example
0x8000000 is a negative number as a log, or 32 bit integer. 0x80000000 as an integer on a 64 bit platform is a positive number. to directly set the sign bit you would have to use 0x80000000 00000000 (embedded space for readability only)
Also I expect size__t to grow appropriately. If you are making any allocations based on MAX_INT, they will be much larger.
To avoid these type of size anomalies, I generally stick with longs instead of ints.
32 位程序可以在 64 位 Windows 上正常运行。 当然,只要您不进行任何设备驱动程序开发即可。
如果您第一次将软件编译为 64 位软件,则需要注意以下事项:
32bit programs will run fine on 64 bit windows. As long you are not doing any device driver kind of development of course.
If you compile your software as a 64 bit software the first time, you need to take care of following:
如果您出于任何原因进行 DLL 注入,您将会遇到麻烦。
If you do DLL injection for any reason you will have trouble.
如果您拥有 100%“类型安全的托管代码”,那么迁移 .NET 代码可能会更容易。
您只需将其复制到64位平台并在64位CLR下成功运行即可。
检查此 MSDN 链接,了解如何将 32 位托管代码迁移到 64 位 -少量。
顺便说一句,hanselman 最近博客讨论了该主题。
It might be easier to migrate .NET code if you have 100% "type safe managed code".
You can just copy it to the 64-bit platform and run it successfully under the 64-bit CLR.
Check this MSDN link on migrating 32-bit Managed code to 64-bit.
Btw, hanselman blogged about the topic recently.
如果您谈论的是 32 位程序,那么您几乎无需担心,因为 Windows 64 会将它们作为 32 位模拟运行。 未来 Windows 版本(例如 Windows 7)的任何问题都可能是不兼容问题,而不是 64 位操作系统的问题。
但是,如果您的托管代码是针对“任何 CPU”目标平台编译的,并且您调用非托管代码(例如 PInvoke),或者依赖于其他程序集,则需要注意一些事项。 Scott Hanselman 关于 x86/x64 的 帖子 CLR 涵盖了这一点,并且很好地解释了 Win32/64 上的 CLR。
开发 64 位本机程序时,请参阅 64 位编程指南-bit Windows 是一个很好的指南。 它很大程度上取决于指针和数据类型的大小:)
If you are talking about 32-bit programs then you have practically nothing to worry about since Windows 64 will run them under emulation as 32-bit. Any problems with future Windows versions (e.g Windows 7) are likely to be incompatibilities rather than issues with a 64-bit OS.
However if your managed code is compiled for the "Any CPU" target platform and you make calls into unmanaged code (e.g PInvoke), or are dependent on other assemblies then there are some things to be aware of. Scott Hanselman's post about the x86/x64 CLR covers this and is a good explanation of the CLR on Win32/64.
When developing 64-bit native programs then the Programming Guide for 64-bit Windows is a good guide. It largely comes down to pointers and the size of data types :)
文章:
在 64 位平台上移植 C++ 代码的 20 个问题
64位程序开发中被遗忘的问题
64 位、Wp64、Visual Studio 2008、Viva64 以及所有其他...
将 C 和 C++ 代码迁移到 64 位 Windows 期间捕获检测
AMD64 (EM64T) 架构
和
Viva64 工具 - 用于检查 64 位程序:
Viva64:它是什么以及它对谁意味着?
Articles:
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
AMD64 (EM64T) architecture
And
Viva64 tool - for check 64-bit programs:
Viva64: what is it and for whom is it meant?
就我而言,将 C/C++ 代码移植到 64 位 Windows 的最重要的事情是在启用
MEM_TOP_DOWN
分配的情况下测试您的应用程序 (AllocationPreference
)代码>注册表值),如4-中所述千兆字节调整:这什么时候重要?
/LARGEADDRESSAWARE< 构建的/code>
MSVC 链接器选项(或者通过其他方式(例如
editbin.exe
)在其 PE 标头中设置了IMAGE_FILE_LARGE_ADDRESS_AWARE
标志),然后它们得到64 位 Windows 中完整的 4 GB 虚拟地址空间,并且您必须使用AllocationPreference
注册表值集来测试它们。AllocationPreference
注册表值集来测试它们。AllocationPreference
注册表值集对其进行测试。如果您的 C/C++ 应用程序属于这三个类别之一,并且您没有使用
MEM_TOP_DOWN
分配进行测试,则测试不太可能捕获代码中的任何指针截断/符号性错误。第二重要的事情是,如果您使用 MSVC 并且要重新编译 64 位 C/C++ 代码,则使用
/Wp64
编译器选项64 位< /em> build:reinterpret_cast
或C风格转换),以及其他一些 64 位移植问题。/Wp64 进行编译
您应该使用针对 64 位平台的编译器,但仅此一点无法在编译时捕获指针截断/扩展问题。 使用针对 64 位的编译器并为 64 位构建启用/Wp64
编译器选项将在编译时捕获许多指针截断/扩展问题,这将从长远来看可以节省您的时间。/Wp64
选项已弃用。 我明白为什么该选项在 32 位构建中被弃用(它是一种邪恶的 hack,需要注释许多 typedef),但不幸的是,它在 64 位构建中也被弃用(它实际上很有用)。As far as I'm concerned, the single most important thing about porting C/C++ code to 64-bit Windows is to test your application with
MEM_TOP_DOWN
allocations enabled (AllocationPreference
registry value) as described in 4-Gigabyte Tuning:When does this matter?
/LARGEADDRESSAWARE
MSVC linker option (or which have theIMAGE_FILE_LARGE_ADDRESS_AWARE
flag set in their PE headers through other means, such aseditbin.exe
), then they get a full 4 GB of virtual address space in 64-bit Windows, and you must test them with theAllocationPreference
registry value set.AllocationPreference
registry value set.AllocationPreference
registry value set.If your C/C++ application falls into one of these three categories and you don't test with
MEM_TOP_DOWN
allocations, testing is very unlikely to catch any pointer truncation/signedness bugs in your code.The second most important thing, if you use MSVC and you are recompiling C/C++ code for 64-bit, is to use the
/Wp64
compiler option for your 64-bit build:reinterpret_cast
or a C-style cast is used), as well as a few other 64-bit porting issues./Wp64
you should use a compiler that targets a 64-bit platform, but that alone will not catch pointer truncation/extension issues at compile time. Using a compiler that targets 64-bit and enabling the/Wp64
compiler option for the 64-bit build will catch many pointer truncation/extension issues at compile time, and this will save you time in the long run./Wp64
option is deprecated. I can see why the option is deprecated for 32-bit builds (where it is an evil hack that requires annotating many of your typedefs), but it's unfortunate that it is also deprecated for 64-bit builds (where it is actually useful).