2010-09-09 92 views
0

我正在研究支持两个通信接口的C#应用​​程序,每个通信接口都支持它自己的DLL。每个DLL包含相同的函数名称,但其实现取决于支持的接口略有不同。实际上,用户通常只在他们的机器上安装一个DLL,而不是两者。旧接口的DLL是这样导入的:在运行时动态加载DLL

[DllImport("myOldDll.dll", 
      CharSet = CharSet.Auto, 
      CallingConvention = CallingConvention.StdCall)] 
public static extern int MyFunc1(void); 
public static extern int MyFunc2(void); 
public static extern int MyFunc3(void); 

这是试图引入任一DLL的有效方法吗?

[DllImport("myOldDll.dll", 
     CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
[DllImport("myNewDll.dll", 
     CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
public static extern int MyFunc1(void); 
public static extern int MyFunc2(void); 
public static extern int MyFunc3(void); 

理想情况下,我想这将是很好的检测缺少DLL,如果先装入尝试失败加载DLL第二。有没有一种优雅的方式来做到这一点?

回答

0

如何做一个P/Invoke到`LoadLibrary'?

+0

然后你会使用获得的句柄吗? GetProcAddress和下一步是什么? – 2010-09-09 19:53:30

+0

什么都没有。如果我得到了句柄,我会释放它并通过使用该DLL名称的extern进行调用。如果没有,我会尝试下一个DLL。 – 2010-09-09 19:58:57

0

在.NET 1.1中,您需要创建一个代理非托管DLL(将其写入C或Delphi或...)并将其称为方法,而非托管DLL将完成剩下的工作。在.NET 2.0和更高版本中,您可以使用Assembly.LoadFile()和更多。不像你试图使用的声明那么优雅,并且需要相当多的编码。所以如果可能的话,我会建议一种代理方式。

0

也许你应该从DLL中导入不同名称的方法,然后在你的程序中有一个委托,指向一个或另一个(无论哪个都合适),只调用委托。

+0

DLL没有理由导出不同的名称:您可以在引用上将它们别名。 – 2010-09-09 19:59:43

0

这听起来像你最好的服务重新架构到模块化插件风格的界面。

在网络上有这样一个十亿半的例子,like this one。简而言之,您在DLL的目录上使用LoadAssembly(),然后转回到您的通用基础接口。