从32位版本迁移到64位版本

本文关键字:版本 64位 迁移 32位 | 更新日期: 2023-09-27 18:27:53

我们在64位机器上进行测试时,一直在进行32位构建。为了在我们的应用程序中利用机器的强大功能,我们计划为我们的C#/.NET 4.0代码库进行64位构建。我们过去从未做过,也没有测试过,尽管它看起来很简单,但我们想了解以下内容:

  • 在迁移过程中,我们需要采取哪些必要步骤
  • 在这次迁移过程中,我们会遇到什么问题?坦率地说,我不确定我们可能会遇到什么问题?像我们的代码引用32位版本的底层DLL这样的东西?我们需要更新所有参考资料吗?同样,我们在这里没有太多的见解,所以这个具体的问题可能无关紧要。但我们希望了解任何可能阻碍平稳过渡的问题
  • 我们对32位进行了所有功能测试。我们可能没有太多时间对64位进行严格的测试?依赖我们的32位功能测试是一种安全的策略吗

从32位版本迁移到64位版本

在简单的情况下,将C#代码从32位移动到64位只是更改构建设置的问题。安全的C#代码在64位体系结构上的执行方式与在32位体系结构中的执行方式相同。

在实践中,您可能会遇到几个问题。以下是一些需要注意的内容:

  • 您的C#代码是否包含不安全的代码

    不安全的代码可以操作指针,因此它可能以假定32位指针的方式编写。要了解您的项目是否包含不安全的代码,您可以在代码库中搜索"unsafe"关键字。

  • 您正在使用p/Invoke吗

    如果使用p/Invoke调用本机代码,CLR运行时现在将查找64位DLL,而不是32位DLL。如果在运行时没有找到64位DLL,您将得到一个异常("BadImageFormatException"或类似的东西)

    您可以在代码库中搜索"DllImport"以查看是否使用p/Invoke。

  • 您的项目是否包含脆性代码

    将项目迁移到64位之后,您将使用不同版本的实时(JIT)编译器。与X86 JIT相比,X64 JIT编译器执行一些更积极的优化。因此,一些在X86中运行的错误编写(通常是多线程)代码可能会在X64上崩溃。

  • 您是否使用某些功能,如封送处理、序列化和COM互操作

    所有这些功能的使用可能需要在64位构建中进行修改。在代码中搜索的一些关键字包括"Marshal"、"StructLayout"、"FieldOffset"、"BinaryFormatter"answers"Com"。

另请参阅本白皮书,该白皮书进一步讨论了将32位托管代码迁移到64位:http://msdn.microsoft.com/en-us/library/ms973190.aspx

是的,您需要确保您引用的所有DLL都有64位版本。不,依赖32位测试是绝对不安全的!(你已经知道了,对吧?)

几年前,我们将系统移植到了64位,并对以下几件事感到惊讶:

  • 总的来说,港口比我们预想的要容易得多
  • 最困难的问题出现在最奇怪的地方,我们认为这些地方会很简单
  • 后续的构建没有出现问题

一些意外和棘手问题的例子。。。

我们的系统包括一个Visual Studio项目向导。Visual Studio仅限32位,但我们的客户可能仍然希望以64位计算机为目标。所以我们的x86安装程序必须包含x64程序集。通常情况下,这是可以的-安装程序发现我们在x86项目中包含x64文件,会发出警告,但会继续。但其中一个程序集包含混合的托管/非托管代码,我们的安装程序无法处理此问题。(当时我们使用的是Visual Studio安装程序,但从那时起我们就长大了。)因此,我们编写了一个工具,对64位DLL进行十六进制编码,并将其写入文本文件,将该文件包含在安装程序项目中,然后有一个自定义的安装程序步骤来反转编码并恢复DLL。

我们的项目向导依赖于一些COM DLL,这些DLL必须在32位注册表中注册,因为Visual Studio是32位的。但在x64上,我们的安装程序以64位运行,因此调用了64位regsvr32.exe,它将DLL注册在错误的位置。因此,我们编写了一个64位工具,在32位注册表中注册DLL。

碰巧我们的向导需要知道我们的产品安装在哪里。因此,我们的安装程序将该信息写入注册表。但在x64上,安装程序以64位运行,并将信息写入64位注册表,但我们的向导在Visual Studio中以32位运行,因此无法读取注册表的这一部分。因此,我们不得不再次编写一个特殊的工具,让安装程序将信息写入注册表的两侧。

这些问题听起来可能并不那么糟糕。毕竟,解决方案非常整洁,而且非常小。但考虑一下:我们的系统是托管/非托管的COM/C++和C#混合的,带有第三方库,如Boost、Apache HTTPd和OpenSSL,所有这些都必须重新编译。我本以为这是最困难的部分,但移植相关代码并编译项目只花了两天时间。然后又花了整整一周的时间来理解和解决我上面描述的问题。话虽如此,我仍然非常惊喜,整个港口只用了一周半的时间。

临别之思。。。你说你想利用64位机器的强大功能。这是什么意思?粗略地说,除非你需要访问超过2GB的RAM,否则你不会从64位运行中获得任何好处。

如果您只使用安全的托管代码,而没有第三方DLL,那么您应该期待一个足够简单的迁移。

不过,你确实想测试所有东西,因为一旦产品发生重大变化,测试它通常是个好主意。您可能会发现一些在64位上失败的非常奇怪的事件。

不,依赖32位功能测试不是一个安全的策略!你的问题很好,很有意义。我惊讶地发现,在我的32位应用程序中,正常工作的功能行为存在显著差异。有关更多详细信息,请参阅编译64位时是什么导致FP精度显著损失(注意:负面评级是由于格式不正确,我已经更改了)