使用来自外部"插件的C ++类引用"无法访问类实现的库

时间:2015-10-12 00:02:04

标签: c++ plugins linker shared-libraries

我正在为我的项目使用Boost.DLL库,以便将其功能卸载到一组可插拔模块中。核心应用程序提供了定义各种结构和类的标头,这些结构和类将在核心应用程序中使用,并且(在某些情况下)将在需要执行各种任务时传递给插件。

我需要做的一件事是将类ServiceCatalog传递给每个插件的初始化方法,以允许该插件向核心应用程序注册各种功能。我已将我希望与我的插件共享的定义分组到名为core.h的标头中,并且我在更多应用程序和我的插件项目中都引用了此标头。

ServiceCatalog有许多较大的函数,对我而言,卸载到cpp文件中是有意义的,而不是试图将它们全部捆绑到头文件中。我仍然喜欢这个插件来了解"形状"但是,因为虽然我不需要它来实例化类,但我需要它能够调用实例方法。

但是因为我引用了插件中的头文件,而不是包含实现的cpp文件,我得到了#34;未解析的外部符号"链接时出错。这在基本层面上是有意义的(即如果插件试图实例化它无法访问实现的内容会发生什么?)但是似乎没有任何方式(我可以找到)声明该类是,我猜," extern"还是什么?

我是否真的需要使用基本抽象类来实现这一目标?这样的解决方案感觉有点复杂。我想我可以用包含一些函数指针的结构代替我的类。

您推荐什么方法?简而言之,我希望我的核心应用程序能够将事物的实例传递给我的插件,其中每个事物都有许多可以调用的相关方法。

// core.h, "main.exe"
class ServiceCatalog
{
public:
  void complex_method_with_external_implementation();
}

//plugin.cpp, "plugin.dll"
#include "core.h"
void register_plugin(ServiceCatalog* catalog)
{
  catalog->complex_method_with_external_implementation();
}

1 个答案:

答案 0 :(得分:1)

如果我理解这一点,ServiceCatalog对象只能由“main.exe”程序创建,而不能在任何插件中创建。如果是这种情况,您可以将插件可以调用的函数声明为virtual

class ServiceCatalog
{
public:
  virtual void complex_method_with_external_implementation();
}

然后所有对它们的引用都将在vtable中,由构造函数引用。插件将通过vtable访问函数,因此它们不需要任何类型的导出。

版本控制存在问题,因为添加新的“导出”需要以不破坏vtable的现有布局的方式完成(您需要在所有现有虚拟函数之后添加它们,而不是在它们之间插入它们)两个现有的虚函数),你也不能删除任何一个,而不用其他东西替换它们。