编译适用于混合平台(32位,64位)并引用在运行时解析的32位或64位DLL

5
在Windows 32位或64位下使用VS2010。我们的C#应用程序调用一个第三方DLL(托管),该DLL与非托管DLL进行接口交互。第三方DLL API在32位或64位下看起来相同,尽管底层链接到32位或64位的非托管DLL。
我们希望我们的C#应用程序能在32位或64位操作系统上运行,最好能自动检测操作系统并通过一个简单的工厂类加载适当的32位第三方DLL - 通过测试环境。因此,最简洁的解决方案将是包含以下内容的运行时文件夹: OurApp.exe 3rdParty32.DLL 3rdPartyUnmanaged32.DLL 3rdParty64.DLL 3rdPartyUnmanaged64.DLL
然而,托管的第三方32位和64位dll的接口是相同的,因此不能在同一VS2010项目中引用两个dll:添加第二个时会显示警告三角形,并且不会被引用。
我的唯一答案是创建两个额外的库DLL项目来引用第三方32位和64位Dll吗?所以我最终会得到这个项目安排: Project 1: Builds OurApp.exe, dynamically creates an object for project2 or project3. Project 2: Builds OurApp32.DLL which references 3rdParty32.dll Project 3: Builds OurApp64.DLL which references 3rdParty64.dll
4个回答

5

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


2
简单的常识解决方案加1分。逻辑上不同的架构应该有不同的构建方式。目标机器的操作系统不会神奇地从32位变成64位,你的软件也不应该如此。让安装程序确定需要部署什么,这就是安装程序的作用。 - AJG85

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

0

这里有一个想法,通过定制您的构建过程应该是可行的:

让您的项目编译两次,生成 YourApp32.exe 和 YourApp64.exe,并相应地修改引用。然后再创建第三个项目,使用引导程序 YourApp.exe,它将仅检查系统的位数并加载 YourApp32.exe 或 YourApp64.exe。

当然,这可能只适用于发布版本,因为您实际上会将编译时间加倍,这对开发人员来说可能很烦人。


0

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

但是,根据第三方托管DLL类型层级结构的复杂性,这条路线可能有更多的工作选择。

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

这是一种非常hacky的方法。如果您有选择,获取第三方提供DLL的选项,并查看是否可以说服他们将与其两个DLL匹配的抽象类或接口公开到第三个程序集中,然后您可以引用该程序集,而无需使用委托进行所有混淆。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接