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

标签 c++ .net manifest gac mixed-mode

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

  1. 实现 ODBC (C) API 的 DLL,主要用 C++ 实现, 一些用 C++/CLI 编写的“粘合”代码,用于与 #2、#3 和 #4 交互

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

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

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

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

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

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

最佳答案

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

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

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

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

补充阅读:

关于c++ - 如何在不使用 GAC 的情况下使 C++/CLI DLL 解析对托管程序集 (DLL) 的依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58089153/

相关文章:

c++ - 在 ubuntu C++ 中使用 FTP 上传 Libcurl 错误

c++ - 从可调用元组的结果创建元组

c++ - 使用资源中的对话

.net - (TTFB) 某些特定请求花费的时间比执行实际请求的时间长

windows - 如何从 Qt 生成带有应用程序 list 的 Visual Studio 项目?

java - 使用 Java 读取 .jar list 文件

c++ - _T 宏会影响 std::string 构造函数吗?

.net - VB.NET 使用 system.net.tcpclient 编写 telnet 客户端

c# - 保存字符串中的重复值

java - 如果从最近使用的应用程序中删除应用程序,Android Oreo 接收器将停止