博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Write Your software base on plugin(C/C++ ABI)
阅读量:6966 次
发布时间:2019-06-27

本文共 6016 字,大约阅读时间需要 20 分钟。

一个软件,如果把所有的功能写进C++源码,维护,扩展,编译都特别麻烦。

共享库后缀名。Linux -> .so  Windows -> .dll

关于动态符号显示问题,具体可以看系统的API,现在做了个只支持Linux.

 Linux 查看一个动态库的符号 nm -D plugin.so

 

注意Linux如果不设置符号隐藏,那么默认的动态库所有的符号都是暴露的。可以用下面的语句设置符号是可暴露。

#define TopVertexAPI __attribute__ ((visibility("default")))

 

为什么不读取C++类的符号,因为每个编译器编译C++的函数符号都是不一样,所以将要暴露的符号全部定义为C符号,

C符号不会被修饰。好做跨平台。关键字:extern "C"

 

设计方法:GLY_Plugin.h 主要管理插件读取,插件释放内存,查找符号。

  GLY_MessagePluginAPI.h 主要是纯虚类,提供给用户的API

  GLY_PluginRegister.h 主要是做符号显示隐藏

 

1 // 2 // Created by gearslogy on 5/9/16. 3 // 4  5 #ifndef API_DESIGN_GLY_PLUGIN_H 6 #define API_DESIGN_GLY_PLUGIN_H 7  8 #include 
9 class GLY_Plugin10 {11 public:12 GLY_Plugin(std::string file);13 ~GLY_Plugin();14 void *operator->();15 void *getPlugin();16 private:17 std::string _dso_file;18 void *_handle;19 20 //a pointer to a function can point to -> void * plugin_creator ()21 typedef void* (*plugin_creator)();22 23 // now create point can point any like -> void * plugin_creator ()24 plugin_creator creator;25 26 //27 typedef void (*plugin_destroy)(void *);28 plugin_destroy destroyer;29 30 //plugin instance ,instance is a class handle31 void *_instance;32 };33 34 35 #endif //API_DESIGN_GLY_PLUGIN_H
GLY_Plugin.h

 

1 // 2 // Created by gearslogy on 5/9/16. 3 // 4 #ifdef __GNUC__ 5     #include 
6 #endif 7 #include "GLY_Plugin.h" 8 #include
9 10 11 GLY_Plugin::GLY_Plugin(std::string file)12 {13 14 15 _dso_file = file;16 _handle = NULL;17 _instance = NULL;18 19 20 // LINUX platform21 #ifdef __GNUC__22 _handle = dlopen(_dso_file.c_str(),RTLD_LAZY);23 if(!_handle)24 {25 std::string so_open_error = file + " open error ";26 throw so_open_error;27 }28 29 30 //@creator() function return a pointers to the C++ class(_instance)31 creator = (plugin_creator)dlsym(_handle,"plugin_create"); // search the signal plugin_create32 if(creator == NULL)33 {34 dlclose(_handle);35 throw "plugin creator not found ";36 }37 destroyer = (plugin_destroy)dlsym(_handle, "plugin_destroy");38 if(destroyer == NULL)39 {40 dlclose(_handle);41 throw "plugin destroyer not found";42 }43 44 try45 {46 _instance = creator();47 }48 catch (...)49 {50 dlclose(_handle);51 _handle= NULL;52 throw std::exception();53 }54 #endif55 56 }57 GLY_Plugin::~GLY_Plugin()58 {59 if(_instance)60 {61 printf("GLY_Plugin Free the instance %s \n",_dso_file.c_str());62 destroyer(_instance); //free your dynamic library63 }64 if(_handle)65 {66 printf("GLY_Plugin Free the handle %s \n",_dso_file.c_str());67 dlclose(_handle); // close the dynamic.so68 }69 }70 void *GLY_Plugin::operator->()71 {72 return _instance;73 }74 void *GLY_Plugin::getPlugin()75 {76 return _instance;77 }
GLY_Plugin.cpp

 

1 // 2 // Created by gearslogy on 5/9/16. 3 // 4  5 #ifndef API_DESIGN_GLY_MESSAGEPLUGINAPI_H 6 #define API_DESIGN_GLY_MESSAGEPLUGINAPI_H 7  8  9 10 11 class MessagePlugin_interface12 {13 public:14     MessagePlugin_interface(){};15     virtual void cookMyMessage()=0;16     virtual ~MessagePlugin_interface(){};17 18 };19 20 21 #endif //API_DESIGN_GLY_MESSAGEPLUGINAPI_H
GLY_MessagePluginAPI.h

 

1 // 2 // Created by gearslogy on 5/10/16. 3 // 4  5 #ifndef API_DESIGN_GLY_PLUGINREGISTER_H 6 #define API_DESIGN_GLY_PLUGINREGISTER_H 7  8 #ifdef _WIN32 9     #define TopVertexAPI __declspec(dllexport)10 #else11     #define TopVertexAPI __attribute__ ((visibility("default")))12 #endif13 14 #define TopVertexHiddenAPI __attribute__((visibility("hidden")))15 16 17 18 // do not use C++ function style.19 extern "C" TopVertexAPI void *plugin_create();20 extern "C" TopVertexAPI void plugin_destroy(void *);21 22 23 #endif //API_DESIGN_GLY_PLUGINREGISTER_H
GLY_PluginRegister.h

 

主程序:

#include 
#include "GLY_Plugin.h"#include "GLY_MessagePluginAPI.h"using namespace std;int main(){ GLY_Plugin MessagePlugin_dyn("./libapi_plugin.so"); MessagePlugin_interface *message_plugin_handle = (MessagePlugin_interface*) (MessagePlugin_dyn.getPlugin()); message_plugin_handle->cookMyMessage(); return 0;}

 

 

制作一个插件

#include 
#include
#include
class Message_Plugin:public MessagePlugin_interface{public: Message_Plugin() { } void cookMyMessage() { printf("MessagePlugin cookMyMessage Houdini function \n"); } static Message_Plugin * plugin_create() { return new Message_Plugin; // create the class pointer } static void *plugin_destroy(Message_Plugin *plugin) { delete plugin; } virtual ~Message_Plugin() { }};void *plugin_create(){ printf("plugin loading\n"); return Message_Plugin::plugin_create(); // for our plugin system}void plugin_destroy(void *plugin){ printf("plugin unloading\n"); Message_Plugin::plugin_destroy((Message_Plugin*) plugin );}

 

 

主程序运行结果:

plugin loading

MessagePlugin cookMyMessage Houdini function
GLY_Plugin Free the instance ./libapi_plugin.so
plugin unloading
GLY_Plugin Free the handle  ./libapi_plugin.so

 

 

GCC对一些属性的定义:

#if defined _WIN32 || defined __CYGWIN__  #ifdef BUILDING_DLL    #ifdef __GNUC__      #define DLL_PUBLIC __attribute__ ((dllexport))    #else      #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.    #endif  #else    #ifdef __GNUC__      #define DLL_PUBLIC __attribute__ ((dllimport))    #else      #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.    #endif  #endif  #define DLL_LOCAL#else  #if __GNUC__ >= 4    #define DLL_PUBLIC __attribute__ ((visibility ("default")))    #define DLL_LOCAL  __attribute__ ((visibility ("hidden")))  #else    #define DLL_PUBLIC    #define DLL_LOCAL  #endif#endif

 

转载于:https://www.cnblogs.com/gearslogy/p/5478646.html

你可能感兴趣的文章
3. 爬虫框架Clawler 爬取优酷电影名
查看>>
记维护旧项目遇到的问题
查看>>
Node v10.15.3 (LTS) 发布,服务器端的 JavaScript 运行环境
查看>>
如何让你的网站拥有网盘功能, 一分钟搞定
查看>>
行李箱品牌“July”完成数百万元天使轮融资
查看>>
group by,where,having之间的区别和用法
查看>>
HashMap VS Hashtable
查看>>
MySQL-To-JSON 的 Kafka 生产者
查看>>
[网络篇]ESP8266-SDK教程(五)之SmartConfig、Airkiss等多种配网方式
查看>>
C4C销售订单中业务伙伴的自动决定功能Partner determination procedure
查看>>
关于Java序列化你不知道的事
查看>>
使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。...
查看>>
项目管理助力组织赢在VUCA时代
查看>>
ybg_auth 4.2 版本发布,基于微服务开发业务框架
查看>>
浏览器事件机制中事件触发三个阶段?
查看>>
Python数据分析之糗事百科第二弹
查看>>
[剑指offer] 二叉搜索树与双向链表
查看>>
Java集合框架源码解析之LinkedHashMap
查看>>
读《学习之道》— 放松点,有时候太勤奋也是一种病
查看>>
王者荣耀使用什么编程语言开发的?
查看>>