欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > C++ 插件实现

C++ 插件实现

2025/9/19 16:26:44 来源:https://blog.csdn.net/weixin_43820463/article/details/147011939  浏览:    关键词:C++ 插件实现

什么是插件

插件(Plug-In) 又称:加载项(Add-On), 外接程序(Add-In),扩展(Extension)等等, 是一种通过动态加载功能模块(即插件)来增强主程序功能的软件设计策略。通过制定标准化接口,确保插件与主程序之间的兼容性与独立性,并方便功能拓展。插件技术广泛应用于IDE开发、游戏引擎、多媒体处理等场景。

插件的基本架构

在这里插入图片描述

插件的原理

C++使用动态加载技术即运行时加载:在运行过程中通过系统调用加载,主动加载多个接口一致动态库。

  • (动态链接)通常情况:一个程序启动加载dll是在链接器确定的,并且该符号不能重复
  • 动态加载:程序在运行期主动加载或者卸载,可以有相同的符号
    可以看出来,插件实现在于规范了接口,以保证各个插件的接口统一。而动态加载则保证了插件可以正常加载到程序中。
    从依赖的建立来看,动态链接依赖在链接的时候建立的。一旦exe发布后,这个依赖就存在而不可以打破。动态加载则是在exe运行加载时建立的即exe系统调用加载动态库的时候

动态库的加载时机

  • 动态链接:在exe启动的时候加载
  • 延时加载:在程序运行过程中第一次用到依赖库导出的符号再加载
    • MVSC:/DDLAYLOAD: demo.dll (符号重载决议)在调用函数和
  • 动态加载: 程序员自动控制加载
    • 系统API

实现一个简单的插件

  • plugin
//定义插件的公共接口 
class IPlugin {public:virtual void initialize() = 0;virtual void execute() = 0;virtual void cleanup() = 0; 
};
  • Helloplugin
#include <iostream>
class HelloPlugin : public IPlugin {
public:void initialize() override {std::cout << "HelloPlugin initialized." << std::endl;}void execute() override {std::cout << "Hello from HelloPlugin!" << std::endl;}void cleanup() override {std::cout << "HelloPlugin cleaned up." << std::endl;}
};extern "C" IPlugin* create() {return new HelloPlugin();
}extern "C" void destroy(IPlugin* plugin) {delete plugin;
}
  • Pluginmanager
#include "IPlugin.h"
#include <string>
#include <vector>
#include <dlfcn.h> // Linux下的动态链接库头文件class PluginManager {
public:void loadPlugin(const std::string& path) {void* handle = dlopen(path.c_str(), RTLD_LAZY);if (!handle) {std::cerr << "Cannot load plugin: " << dlerror() << std::endl;return;}// 获取创建插件的函数IPlugin* (*create)();create = (IPlugin* (*)())dlsym(handle, "create");if (!create) {std::cerr << "Cannot load create function: " << dlerror() << std::endl;return;}// 创建插件实例IPlugin* plugin = create();plugin->initialize();plugins.push_back(std::make_pair(plugin, handle));}void executePlugins() {for (auto& p : plugins) {p.first->execute();}}void unloadPlugins() {for (auto& p : plugins) {p.first->cleanup();dlclose(p.second);delete p.first;}plugins.clear();}private:std::vector<std::pair<IPlugin*, void*>> plugins;
};
  • application
#include "PluginManager.h"int main() {PluginManager manager;manager.loadPlugin("./HelloPlugin.so");manager.executePlugins();manager.unloadPlugins();return 0;
}

从上面可以看出来插件的设计主要关注以下几点

  • 动态库加载(跨平台)
  • 内存管理
  • 插件接口如何设计
  • 插件生命周期管理
  • 插件间通信
  • 各个插件的依赖项版本不一致的管理
  • 各个插件的公共库管理

插件系统的拓展

  • 应用层
    • 热插拔(替换新插件)
    • 自动文件检测 (拖入新插件,插件本身的含义)
  • 插件接口
    • 函数注册版 + 配置文件
      • rpc服务

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词