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

发布于 2024-07-13 12:59:51 字数 416 浏览 3 评论 0 原文

我最近的大部分编程都是在 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

扶醉桌前 2024-07-20 12:59:58

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\

油饼 2024-07-20 12:59:57

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

生生漫 2024-07-20 12:59:55

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

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

  • 指针是 64 位宽,而 int 是 32 位宽。 不要将指针存储在整数中,您的代码将会崩溃。
  • 64 位进程需要 64 位 DLL。 如果您依赖第三方 DLL,请确保它们也以 64 位提供。 如果您需要在 32 位进程和 64 位进程之间进行通信,您将需要 Windows 上多种不同 IPC 方式中的一些。 直接调用函数是没有问题的。
  • 64 位 Windows 上的系统目录与 32 位 Windows 上的不同。 如果您有一些硬编码路径,您可能需要再次检查它们。

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:

  • 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.
马蹄踏│碎落叶 2024-07-20 12:59:55

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

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

梦屿孤独相伴 2024-07-20 12:59:54

如果您拥有 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.

冷了相思 2024-07-20 12:59:54

如果您谈论的是 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 :)

书间行客 2024-07-20 12:59:52

就我而言,将 C/C++ 代码移植到 64 位 Windows 的最重要的事情是在启用 MEM_TOP_DOWN 分配的情况下测试您的应用程序 (AllocationPreference)代码>注册表值),如4-中所述千兆字节调整

要出于测试目的强制从较高地址开始分配,然后再从较低地址分配,请在调用 VirtualAlloc 时指定 MEM_TOP_DOWN 或将以下注册表值设置为 0x100000:

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

这什么时候重要?

  • 如果您现有的 32 位 EXE 是使用 /LARGEADDRESSAWARE< 构建的/code> MSVC 链接器选项(或者通过其他方式(例如 editbin.exe)在其 PE 标头中设置了 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志),然后它们得到64 位 Windows 中完整的 4 GB 虚拟地址空间,并且您必须使用 AllocationPreference 注册表值集来测试它们。
  • 如果您现有的 32 位 DLL 可能由大型地址感知 EXE 加载,则必须使用 AllocationPreference 注册表值集来测试它们。
  • 如果将 C/C++ 代码重新编译为 64 位 EXE 或 DLL,则必须使用 AllocationPreference 注册表值集对其进行测试。

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

第二重要的事情是,如果您使用 MSVC 并且要重新编译 64 位 C/C++ 代码,则使用 /Wp64 编译器选项64 位< /em> build

  • 这将导致编译器针对截断指针或将较小的整数类型扩展为指针的类型转换发出警告(即使使用reinterpret_cast或C风格转换),以及其他一些 64 位移植问题。
  • 是的,文档说,而不是使用 /Wp64 进行编译 您应该使用针对 64 位平台的编译器,但仅此一点无法在编译时捕获指针截断/扩展问题。 使用针对 64 位的编译器为 64 位构建启用 /Wp64 编译器选项将在编译时捕获许多指针截断/扩展问题,这将从长远来看可以节省您的时间。
  • 不幸的是,对于 MSVC 2008,这还会为每个翻译单元生成一个“命令行警告”,指出 /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:

To force allocations to allocate from higher addresses before lower addresses for testing purposes, specify MEM_TOP_DOWN when calling VirtualAlloc or set the following registry value to 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 /LARGEADDRESSAWARE MSVC linker option (or which have the IMAGE_FILE_LARGE_ADDRESS_AWARE flag 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 AllocationPreference registry value set.
  • If you have existing 32-bit DLLs that may be loaded by large address aware EXEs, you must test them with the AllocationPreference registry value set.
  • If you recompile your C/C++ code into a 64-bit EXE or DLL, you must test it with the 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:

  • This will cause the compiler to emit warnings for typecasts that truncate pointers or extend smaller integral types into pointers (even when reinterpret_cast or a C-style cast is used), as well as a few other 64-bit porting issues.
  • Yes, the documentation says that instead of compiling with /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.
  • Unfortunately, with MSVC 2008, this will also produce a "command line warning" for each translation unit saying that the /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).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文