【问题标题】:Do I need do need to implicitly link between explicitly loaded shared libraries for interaction?我是否需要在显式加载的共享库之间隐式链接以进行交互?
【发布时间】:2017-08-12 12:42:11
【问题描述】:

见下图。插件实现了核心库的交互。 (QtPlugin) 导出具体的插件类。插件应该能够从核心检索具体的插件类实例并调用其方法。如果我想实现这种交互插件,我是否必须将插件相互链接?

我不知道当符号被解析时会发生什么。据我想象,该过程存储已解析的符号。因此,一旦核心库解析了符号,插件就可以接收其他插件类的对象并在其上调用方法,如果它们具有标头的话。这是真的吗(适用于所有平台)?

关于符号的存储位置以及谁可以访问它的一些通用信息也会很好。

【问题讨论】:

  • “我不知道当符号被解析时会发生什么” - 你可以在那里阅读..
  • 那些隐式链接没有任何意义
  • 你的插件是在运行时动态加载的,还是在编译时由链接器静态加载的?从你的问题看不清楚。
  • 显式链接是关于什么的。在运行时链接。 VTT 为什么这些隐式链接没有意义?插件从核心库接收对象,需要知道类型。
  • @JesperJuhl 不幸的是它非常复杂,我找不到任何好的资源。

标签: c++ dll linker shared-libraries header-files


【解决方案1】:

通常你链接一些东西,所以插件A链接到Core库,因为它需要知道核心实现才能运行,隐式链接不存在,Core内部不知道插件A(也不应该有)所以核心不知道插件 A 或 B,这意味着插件 B 和 A 在不相互链接的情况下也不会相互了解。

在这种模型中,您希望在插件之间保持不可知,并使用接口或抽象类进行通信。 (例如,如果一个插件从Core继承了一些纯虚函数,另一个插件可以持有指向它的指针,并在不知道完整实现的情况下调用它的函数)

通常你链接一些东西,所以插件A链接到Core库,因为它需要知道核心实现才能运行,隐式链接不存在,Core内部不知道插件A(也不应该有)所以核心不知道插件 A 或 B,这意味着插件 B 和 A 在不相互链接的情况下也不会相互了解。

编辑评论:

在这种情况下,您可以使用插件继承的接口。所以在核心库中你创建了一个名为 ITerminal 的类,它有一组没有实现的虚函数(更新、初始化、连接、打开,任何你需要的),然后 pluginA 可以从它继承并给出函数实现.这样其他插件可以持有 ITerminal 的句柄并在其上调用函数,而无需了解 pluginA 的详细信息。要创建它,您需要一个工厂,例如 Core::CreateTerminal,它将返回一个 ITerminal (ITerminal* object = new PluginA();) 现在 pluginB 可以调用 Core::CreateTerminal,这为他们提供了一个具有实现的 ITerminal 的句柄Core 在这种情况下选择的。要扩展它,您可以让插件将自己注册到核心,因此核心只需在插件中调用创建函数,例如 pluginA 可以将自己注册为核心的 ITerminal 类,然后当调用 CreateTerminal 时,它将调用插件来创建特定的目的。这样你就可以在不改变核心或其他插件的情况下交换插件(拥有不同的终端)

【讨论】:

  • 我想允许插件相互依赖。依赖关系将在运行时知道。 libcore 确保在依赖项之前加载依赖项并注入依赖项。用例硬依赖:A 负责所有终端的东西。 B需要打开一个终端。用例可选依赖项:A 提供一个接口来注册处理程序,B 想要注册一个。问题是如何用cpp实现它。
  • 由于时间有点长,我更新了答案以包含对您的评论的反馈
  • 感谢您的帮助,但核心必须独立于接口。我刚刚测试了它。通过链接到其他插件,硬体面是“容易的”。但是可选依赖项很困难,因为我无法链接它们,因为链接器使它们成为硬依赖项。
  • Dll 是可选的,.lib 不是
  • 都是共享库。然而 gcc 抱怨链接时缺少符号,这将在运行时可用
猜你喜欢
  • 1970-01-01
  • 2021-09-08
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-07-22
相关资源
最近更新 更多