gpt4 book ai didi

c++ - 在静态编译和链接时保持共享库插件系统的结构

转载 作者:太空宇宙 更新时间:2023-11-04 14:05:10 25 4
gpt4 key购买 nike

对于我目前正在开发的C++库,我已经看到了基于共享库的插件系统的优势。只要在初始化时扫描的目录中的共享库之一提供该功能,库的用户就可以使用该功能。

使用 dlopen,将在共享库中搜索两个符号:一个函数返回命名它们实现的功能的字符串,另一个创建函数实例化类并返回指向基类的指针。像这样:

在图书馆A

#include "Instance.hpp"
extern "C" const char* type() {
return "InstanceA";
}
//... class InstanceA definition, inherits from Instance
extern "C" Instance* create() {
return new InstanceA();
}

Core 库将扫描插件目录并保留映射字符串->pointerToCreateFunction 以创建新实例。

这真的很方便,而且是一件非常标准的事情。如果用户代码尝试实例化 InstanceX 但没有共享库实现该类型,则会给出错误,但一切都会正常运行。

但此框架也将用于 iOs 开发,App Store 不允许加载第 3 方共享对象。即使在加载静态链接插件的库的自包含版本时,我也想保留这种模块化插件结构。请注意,在项目管理级别,这就像在 CMake 中定义一个变量一样简单,该变量创建插件的静态版本并静态链接它们。这也将排除代码的动态加载部分。

我缺少的是如何反转机制:虽然对于共享对象,核心库将利用文件系统来了解可以使用的实例类型,但我不知道如何“注册”他们没有改变大部分代码,也没有进入静态初始化失败。看起来唯一的方法是通过包含所有可能的 header 并使用像

这样的大开关来替换扫描类型和创建函数的代码
Instance* theInstance;
if (instanceRequired == "instanceA")
theInstance = new InstanceA();
etc etc...

您是否想过一种方法来避免每次添加新实例时都包含所有 header 并不得不更改 Core 中的代码?

最佳答案

我通过那些在 ctor 中调用 register 的讨厌的静态对象来做这些事情。

通过使 map 本身成为本地静态来避免排序问题,因此无论 map 来自何处,都可以在第一次客户端调用时构建。 (通过将线程启动限制在 until-main 时间来避免线程和类似问题,到那时所有重要的事情都被强制执行。)


class RegMap;  // the registry
RegMap& GetRegistry(); // the singleton access function; you can make a separate const/nonconst version or provide another wrapper for registering

// implementation in core.cpp:
RegMap& GetRegistry()
{
static RegMap m;
return m;
}

//in client ctor:
GetRegistry().Register( key, func);

关于c++ - 在静态编译和链接时保持共享库插件系统的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17341113/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com