代码之家  ›  专栏  ›  技术社区  ›  earlNameless

在混合托管/非托管环境中支持多个体系结构的最佳方法是什么?

  •  7
  • earlNameless  · 技术社区  · 14 年前

    我们有一个.NET库正在引用我们的非托管DLL之一,假设:

    • 非托管.dll

    需要添加64位支持。如何组织DLL? 32位和64位版本的DotNet.dll的IL代码将相同。

    方案1

    • 32位库文件夹
      • Unmanaged.dll,编译为32位
      • DotNet.dll,CPU类型为64位

    在这种情况下,使用这些库的开发人员被迫创建两个应用程序:一个32位应用程序和一个64位应用程序。但在这种情况下,他们知道到底发生了什么。

    • 32位库文件夹
      • DotNet.dll,任何CPU的CPU类型
    • 64位库文件夹
      • DotNet.dll,任何CPU的CPU类型
      • unanged.dll,编译为64位

    • 如果使用32位库文件夹,则在64位操作系统上,其进程将崩溃
    • 如果使用64位库文件夹,则在32位操作系统上,其进程将崩溃

    这使得选项1优于选项2。

    方案3

    • 非托管\u x32.dll,编译为32位
    • 非托管\u x64.dll,编译为64位
    • DotNet.dll,任何CPU的CPU类型

    DotNet.dll在运行时将确定它的运行位,然后PInvoke正确的Unmanaged.dll。

    问题

    1. 作为这些库的开发人员,什么选项最有意义?
      1. 对于选项3,如果您使用的是DotNet.dll,是否希望知道库在运行时确定要使用的非托管.dll?
      2. 如何用这些库重新分发应用程序?
    2. 是否缺少一些选项?
    3 回复  |  直到 14 年前
        1
  •  4
  •   Kevin Kibler    14 年前

    我将选择选项3,为AnyCPU编译托管程序集,并为其体系结构命名非托管程序集。我认为这一决定有两个不同的考虑因素:

    托管程序集应该为任何CPU或特定体系结构编译吗?

    我认为.NET开发人员不必为每个体系结构引用单独的文件。我会使用任何CPU,以便有一个dll。

    DLL应该根据其体系结构显式命名吗?

    对于非托管程序集,可能期望为不同体系结构编译的文件具有不同的名称。从技术角度看,不同的文件命名允许您将两个体系结构的文件放在同一个目录中;这意味着在运行时根据体系结构调用不同的文件,但这并不是一个巨大的负担。我会给文件起不同的名字。

        2
  •  2
  •   Adam Robinson    14 年前

    方案3似乎是最简单的,而方案1似乎是最安全的。仅仅从调用哪个库的角度来看,管理它们似乎没有那么困难,除非您处理大量的调用。主要的问题是,您必须两次声明任何给定的函数,对32位和64位版本使用不同的名称,然后只需更改 DllImport 属性指向正确的目标。存根函数必须在运行时决定调用哪一个。

    请注意,撇开物流不谈,没有必要包括 二者都 在库文件夹中。只要不调用对“错误”库的调用,排除它不会产生任何影响。

        3
  •  2
  •   Joshua    14 年前

    我使用可移植的P/Invoke指令为AnyCPU编译DotNet.dll(就像API声明一样)。

    我提供unmanaged_32.bin和unmanaged_64.bin,并在安装时将架构的正确版本作为unmanaged.dll安装。

    一个仍然有效的技巧是安装unmanaged.dll,如下所示:

    x64:C:\Program Files\Common Files\unmanaged.dll

    如果系统路径中有C:\Program Files\Common Files,这将导致P/Invoke自动获取正确的DLL。