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

Azi*_*ziz 1 c# 64-bit

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

  • 在此迁移过程中我们需要采取哪些必要步骤?
  • 如果在迁移期间我们可以期待什么问题?坦率地说,我不确定我们可能面临任何打嗝?就像我们的代码引用了32位版本被引用的底层DLL一样?我们需要更新所有参考文献吗?同样,我们在这里没有太多见解,所以这个具体问题可能无关紧要.但我们想了解任何可能妨碍顺利过渡的问题.
  • 我们在32位上进行了所有功能测试.我们可能没有太多时间在64位上进行严格的测试?依靠我们的32位功能测试是一种安全的策略吗?

Igo*_*sky 10

在简单的情况下,将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位后,您将使用不同版本的Just-in-Time(JIT)编译器.与X86 JIT相比,X64 JIT编译器执行一些更积极的优化.因此,一些错误编写的(通常是多线程的)代码恰好在X86中运行,最终可能会破坏X64.

  • 您是否正在使用编组,序列化和COM互操作等特定功能?

    可能需要在64位版本中修改所有这些功能的用法.在您的代码中搜索的一些关键字包括"Marshal","StructLayout","FieldOffset","BinaryFormatter"和"Com".

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


Cia*_*ing 6

是的,您需要确保您引用的所有 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 位工具,将 DLL 注册到 32 位注册表中。

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

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

临别感想...您说您想利用 64 位计算机的强大功能。这意味着什么?粗略地说,除非您需要访问超过 2GB 的 RAM,否则您不会意识到以 64 位运行有任何巨大的好处。