在运行时选择适当的平台相关 DLL
我目前正在开发 .NET Compact Framework 项目,该项目使用 DotNetZip 来读取 ZIP 文件。该项目分为两部分。一个独立于平台的库,应可用于 CF 项目和桌面项目。这个通用库包含用于提取 ZIP 文件的代码。问题在于 DotNetZip 库有两种不同的 DLL,一种用于 .NET CF,另一种用于 .NET Desktop Framework。无法在桌面框架上使用该库的 CF 版本,反之亦然,但它们共享相同的界面。
如何在 Visual Studio 中组织我的项目,以便能够使用通用邮政编码并动态加载适当的 DLL(然后由邮政编码使用)?也应该可以在 PC 上执行 CF 应用程序,那么有没有办法在运行时选择 DLL?
I'm currently working on project for the .NET Compact Framework which uses DotNetZip for reading ZIP-files. The project is split into two parts. One platform-independent library which should be available for both, a CF project and a desktop project. This common library contains the code for extracting ZIP-files. The problem is that there are two different DLLs of the DotNetZip library, one for .NET CF and one for the .NET Desktop Framework. It's not possible to use the CF version of the library on a Desktop Framework and vice versa but they share the same interface.
How do I organize my projects in Visual Studio to be able to use the common zip-code and dynamically load the appropriate DLL (which then is used by the zip-code)? It should also be possible to execute the CF application on a PC so is there a way to choose the DLL at runtime?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更新:
技术上不受支持但有效的解决方案是 p/Invoke LoadLibrary 并在此过程的早期专门加载正确的 DLL。所有托管库和 p/Invoke 库均“根据需要”加载。当您调用依赖于该程序集中的类型之一的方法时,CLR 将为您加载它们(注意:这是“不受支持”的部分;这是未记录的,并且将来可能会更改CLR 版本)。
该方法之所以有效,是因为如果通过 LoadLibrary 加载程序集,CLR 加载器会“找到”它,并且运行时不会尝试再次加载它。我们在 CF 上使用这个技巧,在进行大量内存分配之前预加载程序集,以避免出现内存不足的情况。
因此,您应该能够执行以下操作:
请注意,以下操作将不起作用:
旧答案;仅适用于桌面框架:
一个技巧是将它们放置在 DLL 加载期间找不到的目录中(例如,可执行文件目录的不同子目录)并处理 AppDomain.AssemblyResove。 David Morton 在他的博客上写了一篇不错的文章。
UPDATE:
A technically unsupported but working solution is to p/Invoke LoadLibrary and specifically load the correct DLL early in the process. All managed and p/Invoke'd libraries are loaded "as needed". The CLR will load them for you when you invoke a method that depends on one of the types in that assembly (note: this is the "unsupported" part; this is not documented and may change in a future CLR version).
The approach works because if an assembly is loaded via
LoadLibrary
, it's "found" by the CLR loader and the runtime will not attempt to load it again. We used this trick on CF to pre-load assemblies before doing much memory allocation to avoid out-of-memory situations.So, you should be able to do:
Note that the following will not work:
Old answer; works on desktop framework only:
One trick is to place them in directories that won't be found during DLL loading (e.g., different subdirectories of your executable's directory) and handle AppDomain.AssemblyResove. David Morton has a decent write-up on his blog.