编辑:
如果中间 DLL 是 .Net 程序集,则可以使用此处提到的方法指定在调用任何使用中间 DLL 的方法之前查找中间 DLL 的位置,而无需更改现有代码。
那么你不能在你的 C# 项目中直接引用 DLL,因为 .Net 程序集在你的Main
方法被调用之前就被发现并加载了。相反,您必须使用或其他方法动态加载中间 DLL AppDomain
,然后通过反射或使用dynamic
对象来使用库。
显然,这会使编程变得非常麻烦。但是,还有另一种方法。您可以编写一个启动程序,加载您的原始应用程序(您可以将 .exe 文件加载为库),并Main
反射性地调用原始程序的方法。为确保加载了正确的中间 DLL,您可以使用此处提到的方法,同时您的启动程序正在加载您的原始应用程序。
以下讨论仍然适用于硬件 DLL。
以下是有效的,如果:
- 您一次只需要一个版本的 dll(在您的应用程序运行的整个期间),并且
- 中间 DLL 的两个版本具有完全相同的 API。
根据 MSDN,DLL 搜索路径包括在 PATH 环境变量下指定的目录。(http://msdn.microsoft.com/en-us/library/7d83bc18%28v=vs.80%29.aspx)。因此,您可以将两个版本的中间 DLL 放在应用程序目录下的单独子目录下,但每个目录下的名称完全相同,例如:
bin\
hardware-intermediate-v1\
intermediate.dll
hardware-intermediate-v2\
intermediate.dll
然后,在启动时,在您的应用程序确定要使用哪个版本之后,您可以将上述目录之一添加到您的 PATH 环境变量中,
using System;
using System.Reflection;
using System.IO;
...
Environment.SetEnvironmentVariable(
"PATH",
Environment.GetEnvironmentVariable("PATH") + ";" +
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +
"\\hardware-intermediate-v1"
);
然后,对 P-Invoke 方法 (DLLImport) 的调用将导致加载相应版本的 DLL。要立即加载所有的 DLL,可以参考DllImport,如何检查 DLL 是否已加载?.
但是,如果您希望在不重新启动应用程序的情况下同时使用两个版本的 DLL,或者如果两个 DLL 在方法名称和/或参数计数/类型级别上存在任何 API 差异,则必须创建两个单独的集合P-Invoke 方法,每个绑定到其相应版本的中间 DLL。