【问题标题】:Compile for mixed platform (32, 64) and reference a 32 or 64 bit DLL resolved at runtime为混合平台(32、64)编译并引用运行时解析的 32 或 64 位 DLL
【发布时间】:2011-05-30 13:01:07
【问题描述】:

在 windows 32 或 64 位下使用 VS2010。 我们的 C# 应用程序调用与非托管 DLL 接口的第 3 方 DLL(托管)。 第 3 方 DLL API 在 32 位或 64 位中看起来是相同的,尽管它下面链接到一个 32 位或 64 位非托管 DLL。

我们希望我们的 C# 应用程序在 32 位或 64 位操作系统上运行,理想情况下,它将自动检测操作系统并加载适当的第 32 方 DLL - 通过一个简单的工厂类来测试环境。所以最简洁的解决方案是一个运行时文件夹,其中包含: OurApp.exe 3rdParty32.DLL 3rdPartyUnmanaged32.DLL 3rdParty64.DLL 3rdPartyUnmanaged64.DLL

但是,托管 3rdParty 32 和 64 dll 的接口是相同的,因此不能在同一个 VS2010 项目中引用两者:添加第二个时,会显示警告三角形,但不会被引用。

创建两个额外的库 DLL 项目来引用 3rdParty 32 和 64 Dll 是我唯一的答案吗?所以我最终会得到这个项目安排: 项目1:构建OurApp.exe,为project2或project3动态创建对象。 项目 2:构建引用 3rdParty32.dll 的 OurApp32.DLL 项目 3:构建引用 3rdParty64.dll 的 OurApp64.DLL

【问题讨论】:

    标签: c# c++ dll


    【解决方案1】:

    由于您拥有特定于 32 位或 64 位的非托管代码,因此您将失去托管代码能够在运行时 JIT 进入任一模式的优势。最简单的方法可能是设置您的 make 文件来构建您的应用程序两次,一次用于 64 位,一次用于 32 位,并使用 csproj 文件中的条件部分来引用 32 位或 64 位非托管 DLL。让安装程序安装在安装时找到的适合平台的二进制文件。

    【讨论】:

    • +1 用于简单的常识解决方案。逻辑上不同的架构应该有不同的构建。目标机器的操作系统不会神奇地从 32 位变为 64 位,您的软件也不会。让安装程序确定需要部署什么,这就是安装的目的。
    【解决方案2】:

    我不能说我以前做过这个,但快速搜索告诉我你可以对接口进行编程并通过反射动态加载库。

    你考虑过吗?

    【讨论】:

      【解决方案3】:

      这是一个想法,应该可以通过自定义构建过程来实现:

      将您的项目编译为 YourApp32.exe 和 YourApp64.exe 两次,并适当地修改引用。然后还使用引导程序 YourApp.exe 创建第三个项目,它只会检查系统的位数并加载 YourApp32.exe 或 YourApp64.exe。

      当然,这可能应该只针对发布版本进行,因为您实际上会加倍编译时间,这会让开发人员感到烦恼。

      【讨论】:

        【解决方案4】:

        一种选择是在您的工厂中使用反射在运行时加载更正后的第 3 方程序集,并创建正确类的实例,并返回对它的引用。然后,您可以将程序集与可执行文件放在同一目录中,并在运行时加载正确的程序集,而无需添加项目引用。但是,这通常使用已知的基本抽象类或来自另一个程序集的接口(通常一个专门用于保存所需声明的程序)。听起来你没有这个。

        但是,根据第 3 方管理的 DLL 的类型层次结构的复杂性,沿着这条路线可能会有一个选项,但工作量会稍微多一些。

        1. 在您自己的项目中创建一组反映第 3 方 dll 结构的类。假设第三方库不太复杂,这可能只是一个具有许多方法的类。如果有的话,您还必须重新创建任何来回传递的结构。
        2. 创建一组与要在 dll 中调用的方法的签名相匹配的委托。例如,诸如string DoFoo(int a, int b) 之类的方法将具有类似于delegate string DoFooDelegate(int a, int b) 的委托。如果方法具有相同的签名,您可以为所有这些使用单个委托。添加到您在第 3 方 DLL 中要调用的每个方法的变量之前创建的类集。因此,您的类将具有一组类似于private DoFooDelegate doFoo; 的成员。然后可以是您认为合适的任何访问级别。
        3. 对于最繁琐的部分(尽管您可能可以使用通用函数来帮助完成大部分工作)。使用这个http://msdn.microsoft.com/en-us/library/ms228976.aspx 和这个http://msdn.microsoft.com/en-us/library/74x8f551.aspx 作为指导,创建包装类的一个实例,将来自第3 方库的每个方法连接到它在你的类中的匹配成员。这应该在您的工厂内完成。完成后,返回新实例。然后,您应该能够通过您的包装类调用第 3 方程序集。

        这是一种非常老套的方法。如果您有选择权,请联系提供 DLL 的第 3 方,看看您是否可以说服他们将与他们的两个 DLL 匹配的抽象类或接口公开到第三个程序集中,然后您可以引用它,而无需到处乱搞与代表。

        【讨论】:

          猜你喜欢
          • 2018-08-04
          • 1970-01-01
          • 2019-05-01
          • 1970-01-01
          • 2010-11-11
          • 1970-01-01
          • 2021-06-25
          • 1970-01-01
          • 2014-08-15
          相关资源
          最近更新 更多