一个软件,如果把所有的功能写进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)的更多相关文章

  1. A Study of WebRTC Security

    转自:http://webrtc-security.github.io/ A Study of WebRTC Security Abstract Web Real-Time Communication ...

  2. What Can Java Technology Do?

    What Can Java Technology Do? The general-purpose(多用途的), high-level Java programming language is a po ...

  3. JDK版本不兼容问题之:一台机器安装多个版本的JDK

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://guojie.blog.51cto.com/59049/45964 我的机器上最开 ...

  4. JAVA学习提高之----安装多个JDK版本的问题

    我的机器上最开始安装的是jdk1.6,后来因为工作需要又安装了jdk1.4.但是,环境变量我并未更改,还是指向jdk1.6的路径的.可是,在cmd窗口输入 Java -version 却得到是1.4. ...

  5. 【转】使用BBB的device tree和cape(重新整理版)

    只要你想用BBB做哪怕一丁点涉及到硬件的东西,你就不可避免地要用到cape和device tree的知识.所以尽管它们看起来很陌生而且有点复杂,但还是得学.其实用起来不难的.下面我只讲使用时必须会的内 ...

  6. 【转】用Device tree overlay掌控Beaglebone Black的硬件资源

    原文网址:https://techfantastic.wordpress.com/2013/11/15/beaglebone-black-device-tree-overlay/ 经过一晚上的Goog ...

  7. 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 ...

  8. NSIS皮肤插件

    原文 NSIS皮肤插件 [有一个更好的皮肤,大家不妨试一下.http://www.flighty.cn/html/bushu/20110413_118.html ] 对于一般的安装不推荐使用皮肤,因为 ...

  9. mybatis枚举映射成tinyint

    第一步:定义顶级枚举接口 public interface BaseEnum<E extends Enum<?>, T> { public T getCode(); publi ...

随机推荐

  1. 72. 求m到n之和

    求m到n之和 int sum(int m, int n) { int i, result = 0; for (i=m; i<=n; i++) result = result+i; return ...

  2. gcc编译命令行依赖库的指定顺序

    gcc链接过程中定义了三个集合:可重定位目标文件集合E.未解析符号集合U和已定义符号集合D,链接基本流程如下: 1) 按命令行指定顺序依次处理每个目标文件和库文件: 2) 如果为目标文件,将其加入集合 ...

  3. Implicit and Explicit Multithreading MULTITHREADING AND CHIP MULTIPROCESSORS

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION The concept of thread ...

  4. 使用 Swift 在 iOS 10 中集成 Siri —— SiriKit 教程

    下载 Xcode 8,配置 iOS 10 和 Swift 3 (可选)通过命令行编译 除 非你想使用命令行编译,使用 Swift 3.0 的工具链并不需要对项目做任何改变.如果你想的话,打开 Xcod ...

  5. ASP.Net的两种开发模式

    一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...

  6. linux实践之程序破解

    linux实践之程序破解 这次的实践是文件破解,让我们从login可执行文件开始吧! 首先我们执行一下这个可执行程序 ①我们希望在不知道密码的情况下,能够登陆进去.且无论密码是什么,都是提示“on y ...

  7. UML之类图

    类(Class)封装了数据和行为,是具有相同属性.操作.关系的对象集合的总称. 类图(Class Dialog)使用系统中不同类来描述系统的静态结构,类图用来描述不同类和它们之间的关系. 类图由三部分 ...

  8. QFileSystemModel

    #include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDi ...

  9. bugs

    2016-09-04 10:24:14.503 Scgl[1035:341694] You've implemented -[<UIApplicationDelegate> applica ...

  10. linux下设置固定IP

    编辑网卡配置文件 vi /etc/sysconfig/network-script/ifcfg-eth0 进入编辑模式 按i键进行编辑修改 DEVICE=eth0 #物理设备名 IPADDR=192. ...