繁体   English   中英

如何在不使用 GAC 的情况下使 C++/CLI DLL 解决对托管程序集 (DLL) 的依赖?

[英]How can you make a C++/CLI DLL resolve a dependency on managed assemblies (DLLs), without using the GAC?

我们目前将 ODBC 驱动程序构建为 4 个 DLL:

  1. A DLL implementing the ODBC (C) API, mostly implemented in C++, with some 'glue' code written in C++/CLI, used to interact with #2, #3, & #4

  2. 一个 DLL 包含一个托管程序集(用 C# 编写),它定义了用于 #1 和 #4 的“基本”接口以相互通信。

  3. 另一个 DLL 包含依赖于#2 的托管程序集,并定义了对#2 中的类的一些扩展
  4. 另一个 DLL 包含一个托管程序集,其中包含驱动程序的“业务逻辑”,这取决于 #2 和 #3

要部署驱动程序,我们将 DSN 配置为指向 #1,并将 #2、#3 和 #4 放入 GAC。

我们有一个客户想要完全避开 GAC。 我知道将#2、#3 和#4 放入与加载#1 'works'的应用程序相同的目录中,但这不是一个好的解决方案,因为许多不同的应用程序可能会使用该驱动程序。

我们如何设置它以便在没有 GAC 的情况下解决依赖关系? 我尝试创建清单文件(基于https://docs.microsoft.com/en-us/windows/win32/sbscs/assembly-manifests ),但这似乎不起作用(EEFileLoadException 异常被抛出,因为它找不到托管程序集,一旦我从 GAC 中删除依赖项就会发生同样的事情)。 我把清单文件和所有的.DLL 放到同一个目录中。

通过一些(可能还不够)谷歌搜索,我找不到任何好的文档/示例。

我不确定我是否完全理解您的问题,但我会尝试回答:

在尝试解决这个问题时,我们应该记住以下几点:

  1. Fusion 不会启动(因此依赖解析),直到您位于未解析类型的第一次出现所在的堆栈帧中。
  2. 我们可以假设 CLR 已经加载到宿主进程中,并且我们至少有一个 Appdomain。 否则,您必须考虑这两种情况 - 特别是被默认情况下不加载 CLR 的进程消耗。在这种情况下您想做什么?自己加载 CLR?隐式?显式?如果是这样,怎么做你配置你的Appdomain?你的App Root在哪里?你的探测路径是什么?

鉴于这两点,您可以订阅AppDomain.AssemblyResolve Event 但是您应该以这种方式重构您的代码,因此 fusion 在您设法订阅之前不会尝试解析您的程序集。 在处理程序中,仅处理正在解析的程序集的事件,并从您想要的任何位置加载它们 - 例如,从您的本机库所在的同一路径加载它们。

补充阅读:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM