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

时间:2010-12-24 23:06:36

标签: c# c++ dll

在Windows 32或64位下使用VS2010。 我们的C#app调用与非托管DLL接口的第三方DLL(托管)。 第三方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

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:0)

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

你考虑过这个吗?

答案 2 :(得分:0)

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

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

当然,这应该只适用于发布版本,因为你有效地将编译时间加倍,这对开发人员来说很烦人。

答案 3 :(得分: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.aspx和此http://msdn.microsoft.com/en-us/library/74x8f551.aspx作为指导,创建包装类的实例,将每个方法从第三方库连接到其类中的匹配成员。这应该在您的工厂内完成。完成后,返回新实例。然后,您应该可以通过包装类调用第三方程序集。
  4. 这是一种非常黑客的做法。如果您有选项,请获取提供DLL的第三方,看看您是否可以说服他们将抽象类或接口与其两个DLL匹配到第三个程序集中,然后您可以引用它,而不是所有的混乱与代表们合作。