首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加载DLL的多个版本

加载DLL的多个版本
EN

Stack Overflow用户
提问于 2013-06-03 07:45:49
回答 2查看 2.5K关注 0票数 6

我有一个C#应用程序,它与一些硬件(USB设备)接口如下:C# application -> intermediate DLL -> hardware DLL -> hardware。中间DLL和硬件DLL与USB设备一起提供,所以我无法控制这些。

中间DLL是我唯一需要包含在VS项目中的,因为这就是我所称的。然后,硬件DLL位于同一个目录中,因此必须自动找到。

一个新版本的硬件设备现在发布了一个不同的硬件DLL。旧DLL与新硬件不兼容,新DLL与旧硬件不兼容。

如何使我的应用程序与这两部分硬件一起工作?我想我需要按需要加载和卸载每个DLL?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-03 18:21:27

下面是我对类似问题的处理方法。我有一部分代码要处理,但我必须在运行时加载dll。因此,我在我的项目中引用它,但是我没有将它放在与我的程序集的其他程序集相同的目录中。相反,在消费代码中,我有一些代码如下所示:

代码语言:javascript
复制
// constructor called from a static constructor elsewhere
MyDllLoader(string hardwareFolder) {
    _hardwareFolder = hardwareFolder;
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    SeeIfAlreadyLoaded();
}


private void SeeIfAlreadyLoaded() {
    // if the assembly is still in the current app domain then the AssemblyResolve event will
    // never fire.
    // Since we need to know where the assembly is, we have to look for it
    // here.
    Assembly[] assems = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly am in assems)
    {
        // if it matches, just mark the local _loaded as true and get as much
        // other information as you need
    }
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
    string name = args.Name;
    if (name.StartsWith("Intermediate.dll,"))
    {
        string candidatePath = Path.Combine(_hardwareFolder, "Intermediate.dll");
        try {
            Assembly assem = Assembly.LoadFrom(candidatePath);
            if (assem != null) {
                _location = candidateFolder;
                _fullPath = candidatePath;
                _loaded = true;
                return assem;
            }
        }
        catch (Exception err) {
            sb.Append(err.Message);
        }
    }
    return null;
}

还有另一种解决办法--这很复杂,但我已经做了,并为你做了工作。您可以声明一个抽象类(比如MyHardwareAbstraction ),它具有所需方法的签名,并根据该接口编写代码。然后编写一些代码,给出程序集的路径,加载并动态定义一个与MyHardwareAbstraction匹配的新类,并使其映射到所需的实际对象的实例上。几年前我写了一个关于如何做到这一点的博客。

这样做的好处是在代码中使用抽象类型,然后适配器编译器将在运行时编译一个新类,该类将使用其他类型作为目标类型来完成该抽象类型。它也相当有效率。

票数 4
EN

Stack Overflow用户

发布于 2013-06-03 08:08:07

如果您希望两个dll在程序中共存,您将不得不使用AppDomains,正如解释的这里

否则,在用户清楚地选择了他需要的版本之后,您可以简单地使用LoadLibrary?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16892132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档