Write Your software base on plugin(C/C++ ABI)
一个软件,如果把所有的功能写进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 主要是做符号显示隐藏
//
// Created by gearslogy on 5/9/16.
// #ifndef API_DESIGN_GLY_PLUGIN_H
#define API_DESIGN_GLY_PLUGIN_H #include <string>
class GLY_Plugin
{
public:
GLY_Plugin(std::string file);
~GLY_Plugin();
void *operator->();
void *getPlugin();
private:
std::string _dso_file;
void *_handle; //a pointer to a function can point to -> void * plugin_creator ()
typedef void* (*plugin_creator)(); // now create point can point any like -> void * plugin_creator ()
plugin_creator creator; //
typedef void (*plugin_destroy)(void *);
plugin_destroy destroyer; //plugin instance ,instance is a class handle
void *_instance;
}; #endif //API_DESIGN_GLY_PLUGIN_H
GLY_Plugin.h
//
// Created by gearslogy on 5/9/16.
//
#ifdef __GNUC__
#include <dlfcn.h>
#endif
#include "GLY_Plugin.h"
#include <stdio.h> GLY_Plugin::GLY_Plugin(std::string file)
{ _dso_file = file;
_handle = NULL;
_instance = NULL; // LINUX platform
#ifdef __GNUC__
_handle = dlopen(_dso_file.c_str(),RTLD_LAZY);
if(!_handle)
{
std::string so_open_error = file + " open error ";
throw so_open_error;
} //@creator() function return a pointers to the C++ class(_instance)
creator = (plugin_creator)dlsym(_handle,"plugin_create"); // search the signal plugin_create
if(creator == NULL)
{
dlclose(_handle);
throw "plugin creator not found ";
}
destroyer = (plugin_destroy)dlsym(_handle, "plugin_destroy");
if(destroyer == NULL)
{
dlclose(_handle);
throw "plugin destroyer not found";
} try
{
_instance = creator();
}
catch (...)
{
dlclose(_handle);
_handle= NULL;
throw std::exception();
}
#endif }
GLY_Plugin::~GLY_Plugin()
{
if(_instance)
{
printf("GLY_Plugin Free the instance %s \n",_dso_file.c_str());
destroyer(_instance); //free your dynamic library
}
if(_handle)
{
printf("GLY_Plugin Free the handle %s \n",_dso_file.c_str());
dlclose(_handle); // close the dynamic.so
}
}
void *GLY_Plugin::operator->()
{
return _instance;
}
void *GLY_Plugin::getPlugin()
{
return _instance;
}
GLY_Plugin.cpp
//
// Created by gearslogy on 5/9/16.
// #ifndef API_DESIGN_GLY_MESSAGEPLUGINAPI_H
#define API_DESIGN_GLY_MESSAGEPLUGINAPI_H class MessagePlugin_interface
{
public:
MessagePlugin_interface(){};
virtual void cookMyMessage()=;
virtual ~MessagePlugin_interface(){}; }; #endif //API_DESIGN_GLY_MESSAGEPLUGINAPI_H
GLY_MessagePluginAPI.h
//
// Created by gearslogy on 5/10/16.
// #ifndef API_DESIGN_GLY_PLUGINREGISTER_H
#define API_DESIGN_GLY_PLUGINREGISTER_H #ifdef _WIN32
#define TopVertexAPI __declspec(dllexport)
#else
#define TopVertexAPI __attribute__ ((visibility("default")))
#endif #define TopVertexHiddenAPI __attribute__((visibility("hidden"))) // do not use C++ function style.
extern "C" TopVertexAPI void *plugin_create();
extern "C" TopVertexAPI void plugin_destroy(void *); #endif //API_DESIGN_GLY_PLUGINREGISTER_H
GLY_PluginRegister.h
主程序:
#include <iostream>
#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 ;
}
制作一个插件
#include <GLY_MessagePluginAPI.h>
#include <stdio.h>
#include <GLY_PluginRegister.h>
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
Write Your software base on plugin(C/C++ ABI)的更多相关文章
- A Study of WebRTC Security
转自:http://webrtc-security.github.io/ A Study of WebRTC Security Abstract Web Real-Time Communication ...
- What Can Java Technology Do?
What Can Java Technology Do? The general-purpose(多用途的), high-level Java programming language is a po ...
- JDK版本不兼容问题之:一台机器安装多个版本的JDK
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://guojie.blog.51cto.com/59049/45964 我的机器上最开 ...
- JAVA学习提高之----安装多个JDK版本的问题
我的机器上最开始安装的是jdk1.6,后来因为工作需要又安装了jdk1.4.但是,环境变量我并未更改,还是指向jdk1.6的路径的.可是,在cmd窗口输入 Java -version 却得到是1.4. ...
- 【转】使用BBB的device tree和cape(重新整理版)
只要你想用BBB做哪怕一丁点涉及到硬件的东西,你就不可避免地要用到cape和device tree的知识.所以尽管它们看起来很陌生而且有点复杂,但还是得学.其实用起来不难的.下面我只讲使用时必须会的内 ...
- 【转】用Device tree overlay掌控Beaglebone Black的硬件资源
原文网址:https://techfantastic.wordpress.com/2013/11/15/beaglebone-black-device-tree-overlay/ 经过一晚上的Goog ...
- find-a-jar-file-given-the-class-name
Save this as findclass.sh (or whatever), put it on your path and make it executable: #!/bin/sh find ...
- NSIS皮肤插件
原文 NSIS皮肤插件 [有一个更好的皮肤,大家不妨试一下.http://www.flighty.cn/html/bushu/20110413_118.html ] 对于一般的安装不推荐使用皮肤,因为 ...
- mybatis枚举映射成tinyint
第一步:定义顶级枚举接口 public interface BaseEnum<E extends Enum<?>, T> { public T getCode(); publi ...
随机推荐
- Ruby-随机数
--随机0-1 rand --随机一个范围 rand(1..100)
- Mysql 数据库之修改标的结构
比如我们新建一user表 create table user( id int unsigned auto_increment primary key, name varchar(60) not nul ...
- 使用Java开发高性能网站需要关注的那些事儿
无论大型门户网站还是中小型垂直类型网站都会对稳定性.性能和可伸缩性有所追求.大型网站的技术经验分享值得我们去学习和借用,但落实到更具体的实践上并不是对所有网站可以适用,其他语言开发的网站我还不敢多说, ...
- 一篇UI规范文件
一篇UI规范文件 这是一个UI模板规范,在做B/S版应用程序时比较适用,其实这样的东西算不上什么正规的规范,只是为了适应我们现在面对的开发环境和组织流程做的一些权宜的努力,和解决了一些与程序沟通和接口 ...
- 2在HTML中使用JavaScript
像HTML页面中插入JavaScrip的主要方法,就是使用<script>元素.HTML4.01为<script>定义了6个属性:async:可选,表示应该立即下载脚本,当不妨 ...
- jiajianhao
#include<stdio.h> int map[4][4]={ 0,1,0,0, 0,0,0,0, 0,0,0,0, 0,1,0,0}; int flag=0; int minci=9 ...
- git学习手册
#git学习手册 git: Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理.[2] Git 是 Linus Torvalds 为了帮助管理 Linux内核开发而 ...
- linux实践之ELF文件分析
linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf ...
- 从偶然的机会发现一个mysql特性到wooyun waf绕过题
从偶然的机会发现一个mysql特性到wooyun waf绕过题 MayIKissYou | 2015-06-19 12:00 最近在测试的时候,偶然的机会发现了一个mysql的特性, 为啥是偶然的机会 ...
- utils.js
/** * //2.0检测方式(目测,测量,专用仪器测试等) function GetCheckType() { $.ajax({ url: '@Url.Action("GetCheckTy ...