【问题标题】:Choose appropriate platform dependent DLL at runtime在运行时选择适当的平台相关 DLL
【发布时间】:2010-07-01 10:20:14
【问题描述】:

我目前正在开发 .NET Compact Framework 项目,该项目使用 DotNetZip 读取 ZIP 文件。该项目分为两部分。一个独立于平台的库,应该可用于 CF 项目和桌面项目。这个公共库包含用于提取 ZIP 文件的代码。问题在于 DotNetZip 库有两种不同的 DLL,一种用于 .NET CF,一种用于 .NET Desktop Framework。无法在桌面框架上使用 CF 版本的库,反之亦然,但它们共享相同的界面。

如何在 Visual Studio 中组织我的项目,以便能够使用公共邮政编码并动态加载适当的 DLL(然后由邮政编码使用)?应该也可以在 PC 上执行 CF 应用程序,那么有没有办法在运行时选择 DLL?

【问题讨论】:

    标签: c# .net dll compact-framework loadlibrary


    【解决方案1】:

    更新:

    一个技术上不受支持但可行的解决方案是 p/Invoke LoadLibrary 并在此过程的早期专门加载正确的 DLL。所有托管和 p/Invoke 的库都“根据需要”加载。当您调用依赖于该程序集中其中一种类型的方法时,CLR 将为您加载它们(注意:这是“不受支持”的部分;这没有记录在案,将来可能会更改CLR 版本)。

    该方法有效,因为如果通过LoadLibrary 加载程序集,CLR 加载程序会“找到”它,并且运行时不会尝试再次加载它。我们在 CF 上使用了这个技巧,在进行大量内存分配之前预加载程序集,以避免内存不足的情况。

    所以,你应该可以做到:

    public static void Main()
    {
        LoadCorrectDLLs();
    
        // .NET will ensure DotNetZip is loaded at this point.
        MethodInThisAssembly();
    }
    
    public static void MethodInThisAssembly()
    {
        // Since MethodInThisAssembly uses DotNetZip,
        //  its assembly will get loaded immediately before this method is called.
        IDotNetZipInterface x = null;
        ...
    }
    
    public static void LoadCorrectDLLs()
    {
        // p/Invoke LoadLibrary to load the correct version of DotNetZip.
    }
    

    请注意,以下操作将起作用:

    public static void Main()
    {
        LoadCorrectDLLs();
    
        // This line would force DotNetZip to get loaded before Main() is called
        IDotNetZipInterface x = null;
    }
    

    旧答案;仅适用于桌面框架:

    一个技巧是将它们放置在 DLL 加载期间找不到的目录中(例如,可执行文件目录的不同子目录)并处理 AppDomain.AssemblyResove。大卫莫顿写了一篇不错的文章on his blog

    【讨论】:

    • 一个问题是紧凑框架中不存在该事件,另一个是我在编译时需要其中一个DLL。
    • 对不起;我不知道我怎么错过了 CF 部分。我已经相应地更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多