引用.net dll + unmanaged dll

时间:2012-04-12 08:38:14

标签: c# .net dllimport

我有一个引用.net dll(称之为instrument-proxy)的项目(称之为平台),它使用DllImport引用C ++ dll(称之为仪器)。仪器和它的代理始终是相同的版本,并且始终部署为一个。

我需要能够在一台机器上部署多个仪器(带有代理),并且只需要一个使用特定版本仪器的平台。

似乎我无法将一个insturent-proxy放置到GAC,因为它使用的是C ++ DLL。我可以将一个工具(和它的代理)安装到一个特定的文件夹,但我怎样才能确保该平台能找到该DLL?

UPD。

理论上我想看到的想法是在正常开发时引用这个dll,但是为了能够让我的应用程序在自定义文件夹中搜索这个dll。

4 个答案:

答案 0 :(得分:2)

将它们保存在单独的文件夹中就可以了。您可以使用Assembly.LoadFrom自行加载正确的仪器 - 代理程序集。然后使用反射从该程序集创建类的实例并进行调用:

Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll");
Type yourClassType = assm.GetType("YourClass");
object yourClassObj = Activator.CreateInstance(yourClassType);
object Result = yourClassType.InvokeMember("DoSomething",
                                            BindingFlags.Default | BindingFlags.InvokeMethod,
                                            null,
                                            yourClassObj,
                                            args);

要避免反射调用InvokeMember,您可以尝试使用interface:

Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll");
Type yourClassType = assm.GetType("YourClass");
YourInterface interf = (YourInterface)Activator.CreateInstance(yourClassType);
interf.DoSomething();

接口需要在一个单独的程序集中,您可以从platform引用它。所有instrument-proxies都必须针对相同版本的接口程序集进行编译。

如果您的instrument-proxy无法找到非托管Instrument.dll,您可以在首次使用前明确加载它:

[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);

IntPtr pDll = LoadLibrary(@"PathTo_Instrument.dll");

完成后免费/卸载:

[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);

答案 1 :(得分:1)

您可以将非托管dll文件复制到文件夹,然后将该文件夹添加到“系统路径变量”,或者将这些文件复制到Windows \ System32,因为此文件夹始终位于“系统路径”中。

要修改系统路径,请右键单击我的计算机 - >属性 - >高级系统设置 - >在高级选项卡下 - >环境变量,您需要找到路径变量,然后修改它以包含您的文件。

将文件复制到Windows \ System32或%systemroot%(通常是C:\ Windows)比较容易,但我建议使用Path变量修改方法

答案 2 :(得分:1)

对于.Net程序集,您可以订阅AppDomain.AssemblyResolve并在需要时使用Assembly.LoadFrom加载程序集(请参阅https://stackoverflow.com/a/10120664/143503)。

答案 3 :(得分:0)

像Maceij上面建议的那样,将你的乐器部署在不同的文件夹中。但是,不要使用反射来加载/实例化乐器,而是看看MEF。

您的确切需求可能需要另外一种方法来执行此操作,但我会让仪器代理[Export]使用以下方法进行IInstrument工厂接口:

IInstrument GetInstrument( string name, int major, int minor );

然后告诉MEF在哪里找到您的仪器并让它创建不同的工厂,然后您可以从中请求所需的仪器。

MEF上的MSDN:http://msdn.microsoft.com/en-us/library/dd460648.aspx