作为程序员,迁移到 64 位 Windows 时需要担心什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/544296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:58:15  来源:igfitidea点击:

As a programmer, what do I need to worry about when moving to 64-bit windows?

windows32bit-64bit

提问by jm.

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.

我最近的大部分编程都是在使用 C/C++/C#/VB6 的 32 位 Windows 上进行的。最近,我的客户问我的代码是否可以在 64 位 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?

我想知道我可能使用的哪些旧功能会在 64 位 Windows 上中断?我需要考虑和担心哪些现实问题?

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).

显然,我将在 64 位操作系统上测试我的代码,但我想知道要查找哪些常见问题。我更关心现有的二进制文件,但我愿意就重新编译时需要担心的问题发表评论(在可能的情况下)。

EDIT: Here is a nice listof 64-bit porting bugs.

编辑:这是一个很好的 64 位移植错误列表

回答by bk1e

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_DOWNallocations enabled (AllocationPreferenceregistry value)as described in 4-Gigabyte Tuning:

就我而言,将 C/C++ 代码移植到 64 位 Windows 的最重要的事情是在启用分配(注册表值)的情况下测试您的应用程序,MEM_TOP_DOWNAllocationPreference4-Gigabyte Tuning 中所述

To force allocations to allocate from higher addresses before lower addresses for testing purposes, specify MEM_TOP_DOWNwhen calling VirtualAllocor set the following registry value to 0x100000:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

要强制分配从较高地址在较低地址之前分配以进行测试,请MEM_TOP_DOWN在调用VirtualAlloc或将以下注册表值设置为 0x100000 时指定:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference

When does this matter?

这什么时候重要?

  • If you have existing 32-bit EXEs that were built with the /LARGEADDRESSAWAREMSVC linker option (or which have the IMAGE_FILE_LARGE_ADDRESS_AWAREflag set in their PE headers through other means, such as editbin.exe), then they get a full 4 GB of virtual address space in 64-bit Windows, and you must test them with the AllocationPreferenceregistry value set.
  • If you have existing 32-bit DLLs that may be loaded by large address aware EXEs, you must test them with the AllocationPreferenceregistry value set.
  • If you recompile your C/C++ code into a 64-bit EXE or DLL, you must test it with the AllocationPreferenceregistry value set.
  • 如果您有使用/LARGEADDRESSAWAREMSVC 链接器选项构建的现有 32 位 EXE (或IMAGE_FILE_LARGE_ADDRESS_AWARE通过其他方式在其 PE 标头中设置标志,例如editbin.exe),那么它们将获得完整的 4 GB 64 位虚拟地址空间Windows,您必须使用AllocationPreference注册表值集测试它们。
  • 如果您有可能由大型地址感知 EXE 加载的现有 32 位 DLL,您必须使用AllocationPreference注册表值集测试它们。
  • 如果将 C/C++ 代码重新编译为 64 位 EXE 或 DLL,则必须使用AllocationPreference注册表值集对其进行测试。

If your C/C++ application falls into one of these three categories and you don't test with MEM_TOP_DOWNallocations, testing is very unlikely to catch any pointer truncation/signedness bugs in your code.

如果您的 C/C++ 应用程序属于这三个类别之一并且您不使用MEM_TOP_DOWN分配进行测试,则测试不太可能在您的代码中捕获任何指针截断/符号错误。

The second most important thing, if you use MSVC and you are recompiling C/C++ code for 64-bit, is to use the /Wp64compiler option for your 64-bitbuild:

第二个最重要的事情是,如果您使用 MSVC 并且正在为 64 位重新编译 C/C++ 代码,则为您的64 位构建使用/Wp64编译器选项

  • This will cause the compiler to emit warnings for typecasts that truncate pointers or extend smaller integral types into pointers (even when reinterpret_castor a C-style cast is used), as well as a few other 64-bit porting issues.
  • Yes, the documentationsays that instead of compiling with /Wp64you 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 andenabling the /Wp64compiler 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.
  • Unfortunately, with MSVC 2008, this will also produce a "command line warning" for each translation unit saying that the /Wp64option 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).
  • 这将导致编译器针对截断指针或将较小的整数类型扩展为指针的类型转换发出警告(即使reinterpret_cast使用 C 样式转换时),以及其他一些 64 位移植问题。
  • 是的,文档/Wp64应该使用面向 64 位平台的编译器而不是与您一起编译,但仅凭这一点不会在编译时捕获指针截断/扩展问题。使用面向 64 位的编译器/Wp64为 64 位构建启用编译器选项将在编译时捕获许多指针截断/扩展问题,从长远来看,这将为您节省时间。
  • 不幸的是,对于 MSVC 2008,这也会为每个翻译单元生成一个“命令行警告”,说明该/Wp64选项已被弃用。我可以理解为什么该选项在 32 位构建中被弃用(它是一个邪恶的黑客,需要对许多 typedef 进行注释),但不幸的是,它也被 64 位构建弃用(它实际上很有用)。

回答by Gulzar Nazim

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 linkon migrating 32-bit Managed code to 64-bit.

如果您拥有 100% 的“类型安全托管代码”,则迁移 .NET 代码可能会更容易。直接复制到64位平台,在64位CLR下运行成功即可。检查有关将 32 位托管代码迁移到 64 位的MSDN 链接

Btw, hanselman bloggedabout the topic recently.

顺便说一句,汉塞尔曼最近在博客上讨论了这个话题。

回答by Andrew Grant

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.

如果您在谈论 32 位程序,那么您几乎无需担心,因为 Windows 64 会将它们作为 32 位在仿真下运行。未来 Windows 版本(例如 Windows 7)的任何问题都可能是不兼容而不是 64 位操作系统的问题。

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 postabout the x86/x64 CLR covers this and is a good explanation of the CLR on Win32/64.

但是,如果您的托管代码是为“任何 CPU”目标平台编译的,并且您调用非托管代码(例如 PInvoke),或者依赖于其他程序集,则需要注意一些事项。Scott Hanselman关于 x86/x64 CLR的帖子涵盖了这一点,并且很好地解释了 Win32/64 上的 CLR。

When developing 64-bit native programs then the Programming Guide for 64-bit Windowsis a good guide. It largely comes down to pointers and the size of data types :)

在开发 64 位本机程序时,64 位 Windows 编程指南是一个很好的指南。它主要归结为指针和数据类型的大小:)

回答by nusi

32bit programs will run fine on 64 bit windows. As long you are not doing any device driver kind of development of course.

32 位程序将在 64 位窗口上正常运行。当然,只要您不进行任何设备驱动程序开发。

If you compile your software as a 64 bit software the first time, you need to take care of following:

如果您第一次将您的软件编译为 64 位软件,您需要注意以下事项:

  • a pointer is 64 bit wide, while an int is 32 bit. Don't store pointers in ints, your code will break.
  • 64 bit process need 64 bit DLLs. If you depend on third part DLLs, make sure they are also provided in 64 bit. If you need to communicate between a 32 bit process and a 64 bit process, you will need some of the many different ways of IPC on Windows. Calling functions directly is out of question.
  • The system directories on 64 bit Windows are different than on 32 bit Windows. If you have some hard coded paths, you might need to check them again.
  • 一个指针是 64 位宽,而一个 int 是 32 位宽。不要将指针存储在整数中,您的代码会中断。
  • 64 位进程需要 64 位 DLL。如果您依赖第三方 DLL,请确保它们也以 64 位提供。如果您需要在 32 位进程和 64 位进程之间进行通信,您将需要 Windows 上许多不同的 IPC 方式中的一些。直接调用函数是没有问题的。
  • 64 位 Windows 上的系统目录与 32 位 Windows 上的不同。如果您有一些硬编码路径,则可能需要再次检查它们。

回答by Joshua

If you do DLL injection for any reason you will have trouble.

如果您出于任何原因进行 DLL 注入,您将遇到麻烦。

回答by jm.

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...

32 位仿真真的防弹吗?我已经看到注册表的布局略有不同。我只是想知道什么典型的东西不起作用......

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:\windows\SYSTEM32 目录只能包含 64 位 DLL。如果你有一个 32 位的 DLL,你需要把它放在 C:\windows\syswow64\

回答by jm.

From a C/C++ perspective....

从 C/C++ 的角度来看......

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.

一个明显的事情是 int 的大小将变为 8 个字节而不是 4 个字节。如果您的任何代码依赖于此,您可能会得到意想不到的结果。结构和变量对齐可能会发生变化。您也许可以使用 #pragma 包来克服它,但我在对齐和打包方面不是很流利。

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.

如果您使用任何位域结构,基于整数的额外 32 位可能会导致混淆。符号位不会在您认为的位置。

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)

如果您编写任何十六进制常量并期望符号变为负数,则您可能会遇到问题。示例 0x8000000 是作为对数的负数或 32 位整数。0x80000000 作为整数在 64 位平台上是一个正数。要直接设置符号位,您必须使用 0x80000000 00000000 (嵌入空间仅供阅读)

Also I expect size__t to grow appropriately. If you are making any allocations based on MAX_INT, they will be much larger.

我也希望 size__t 适当增长。如果您基于 MAX_INT 进行任何分配,它们将大得多。

To avoid these type of size anomalies, I generally stick with longs instead of ints.

为了避免这些类型的大小异常,我通常坚持使用 longs 而不是 ints。