使用来自无法访问 class 实现的外部 "plugin" 库的 C++ class 引用

Consuming a C++ class reference from an external "plugin" library that doesn't have access to the class implementation

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

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

ServiceCatalog 有许多更大的函数,对我来说,将它们卸载到一个 cpp 文件中是有意义的,而不是试图将它们全部捆绑到 header 文件中。不过,我仍然希望插件知道 class 的 "shape",因为虽然我不需要它来实例化 class,但我需要它能够调用实例方法。

但是因为我在插件中引用了 header 文件,而不是包含实现的 cpp 文件,所以在链接时出现 "unresolved external symbol" 错误。这当然在基本层面上是有意义的(即如果插件试图实例化它无法访问实现的东西会发生什么?)但似乎没有任何方法(我能找到)声明 class 是,我猜,"extern" 还是什么?

我真的需要使用基本抽象 class 来实现吗?这样的解决方案感觉有点绕。我想我可以用包含一些函数指针的结构替换我的 class。

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

// 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();
}

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

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

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

版本控制存在问题,因为添加新 'exports' 需要以不会弄乱 vtable 现有布局的方式完成(您需要在所有现有虚函数之后添加它们,而不是将它们插入两个现有的虚函数之间),并且你也不能删除任何一个,除非用其他东西替换它们。