5

我正在使用 FireBreath 框架制作浏览器插件。大多数逻辑都是用 C# 编写的,为了从浏览器中调用它,我制作了一个 C++ 包装器。浏览器调用 C++ 本机代码,该代码调用“代理”托管 C++ 代码,该代码调用 C# 项目中的实际逻辑。

所以我有3个dll:

  • 依赖于托管 C++ 的原生 C++ dll;
  • 托管 C++,它依赖于 C#;
  • 包含主要逻辑的 C# dll。

所有 3 个 dll 都安装到用户目录 (c:\Users\\AppData\Roaming\MyCompany\MyApp\1.0.0.0)

问题是浏览器不加载 C# dll。我使用 Side by Side 清单来声明依赖项。

我试图制作一个单独的清单文件来声明一个程序集:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity name="MyAssembly" processorArchitecture="*" type="win32" version="1.0.0.0"/>
    <file name="FirstDependency.dll"/>
    <file name="SecondDependency.dll"/>
</assembly> 

并将此依赖项的链接添加到头 dll(本机 C++):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity name="MyAssembly" processorArchitecture="*" type="win32" version="1.0.0.0"/>
    </dependentAssembly>
  </dependency>
</assembly>

我还尝试直接在头 dll(Native C++)中声明依赖项:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <file name="FirstDependency.dll"/>
  <file name="SecondDependency.dll"/>
</assembly>

尝试使用 #pragma 指令链接依赖的 dll:

 #pragma comment(linker, "\"/manifestdependency:type='win32' name='FirstDependency' version='1.0.0.0' processorArchitecture='X86' language='*'\"")
 #pragma comment(linker, "\"/manifestdependency:type='win32' name='SecondDependency' version='1.0.0.0' processorArchitecture='X86' language='*'\"")

我使用 Dependency Walker 检查了依赖关系,它确认了托管 C++ 和 C# 之间的依赖关系不存在。

插件可以访问头 dll(本机 C++)并且它也加载托管 C++ 但是当托管 C++ 调用 C# dll 时 - 插件失败,找不到 C# 程序集。

如果我将 C# dll 与浏览器应用程序(firefox.exe 或 chrome.exe)放在同一目录中 - 它可以工作。

看起来并排依赖在托管 C++ 和 C# 之间不起作用。

如何为我的插件加载依赖的 dll?

4

2 回答 2

2

解决了。

向 C++/CLI 代理程序集添加了 ResolveEventHandler 处理程序,该程序集从用户目录加载 C# 程序集。

于 2012-01-24T07:01:47.217 回答
0

恐怕我对 Firebreath 或程序集依赖清单一无所知,但有一个潜在的解决方法。

您是否考虑过使用C++/CLI在 C++ 本机代码和 C# 之间提供包装器?如果您在 VisualStudio 中的 Windows 上编译,只需设置 /clr 开关,就可以使 C++ 库允许混合托管/本机代码。然后,您可以直接从混合的 C++/CLI dll 中引用 C# 程序集并直接调用它。只要 C# 程序集位于同一目录中,它就可以工作。

事实上,您可以更进一步,将整个程序集定义为混合 C++/CLI - 将所有托管元素导入此 DLL。如果您已经在 C# 中有大量代码,我不建议您这样做,但这是将来要考虑的事情。

此致,

于 2012-01-23T12:38:20.053 回答