合 肥 外 围 - 合 肥 哪 有 外 围

  合 肥 外 围 - 合 肥 哪 有 外 围 -薇芯【81343628】【81343628】【高端外围资源】【诚信合作,非诚勿扰!】可直接添加 ! 想到写本博客,也没想到更好的名字,目前就先命这个名吧。说到插件架构,或许大部分IT从业者都听过或者某些牛人也自己实现过稳定高效的插件框架。目前有很多软件以及库都是基于插件架构,例如PS、我所在行业的GIS软件如Arcgis、QGIS、还比如开源图形引擎OGRE以及OSG,这些都是插件架构,通过插件架构来进行功能的扩展。那到底什么是插件架构呢?我的理解是系统运行时在需要某个功能的时候动态加载的模块,插件通常用动态链接库实现,当然也可以用静态库,例如一些嵌入式系统中,比如IOS据说就不支持动态链接库。
  我们为什么要用插件架构呢?
  合 肥 外 围 - 合 肥 哪 有 外 围 -薇芯【81343628】【81343628】【高端外围资源】【诚信合作,非诚勿扰!】可直接添加 !现代软件工程已经从原先的通用程序库逐步过渡到应用程序框架,比如一些C++的库,这些库都是实现某一领域特定功能的,比如GDAL,实现各种空间数据格式的解析,这种库通常不是基于插件架构;应用程序框架比如JAVA里面的三大框架。首先,假设一个场景,以C++开发应用程序为例,我们的架构是基于APP+DLL的传统架构,所有的功能糅杂在一起,这样随着系统的日益庞大,各种模块之间耦合在一起,当修改其中一个模块时,其他模块也跟着一起受到影响,假如这两个模块式不同的开发人员负责的,就需要事先沟通好,这样就造成了修改维护的困难。那怎么解决这个问题,插件架构是一种选择。那么插件架构究竟有哪些好处呢?
  1、方便功能的扩展。比如在GIS引擎设计中,一般的做法是不把数据格式的解析放在GIS内核中,只是在内核中定义一些通用的数据加载解析的接口,然后通过插件来实现某一特定格式的解析,这样就可以扩展各种不同的数据格式,也方便移植。
  2、更新量小。当底层的接口不变时,以插件形式存在的功能很容易独立于应用程序而更新,只需要引入新版本的插件即可。相比发布整个应用程序,这种方式的更新量小很多。
  3、降低模块之间依赖,可以支持并行开发。比如两个开发人员开发不同功能的插件,他们就可以只关心自己插件功能的实现,可以实现快速开发。
  4、面向未来。当你的API到达一定稳定程度后,这时候你的API可能没有更新的必要了。然而API的功能可以通过插件来进一步演化,这使得API可以再长时期内保持其可用性和适用性,使得你的API可以不被抛弃。
  二、插件需要设计的东西
  这里我只考虑动态链接库的情况。我们需要一种加载动态链接库并访问其中符号的机制。在一般的插件系统中,插件API和插件管理器是必须要设计的。
  插件API。这个是创建插件必须要提供的接口,C++实现的话就是一个抽象类,里面只提供接口,具体功能交给插件实现。这部分代码应该在你的核心API之内。
  插件管理器。插件管理器负责插件的加载、注册以及卸载等功能,管理插件的整个生命周期。该类一般都设计为单例模式,其实大部分资源管理的类一般都设计为单例模式。
  插件和核心API之间的关系如下。
  当我们把插件加载进来后,这时候还不知道插件怎么运行,为了让插件正常的运行,这时候需要知道核心API应该访问哪个具体的函数实现插件的正常运转,定义的入口函数,这个可以通过导出标准C接口方式实现插件的初始化、停止等操作。
  下面是具体的定义导出符号和标准C接口的实例。
  #ifdef PLUGINCORE_EXPORTS
  #ifdef __GNUC__
  #define PLUGINCORE_API __attribute__((dllexport))
  #else
  #define PLUGINCORE_API __declspec(dllexport)
  #endif
  #else
  #ifdef __GNUC__
  #define PLUGINCORE_API __attribute__((dllimport))
  #else
  #define PLUGINCORE_API __declspec(dllimport)
  #endif
  #endif
  extern "C" PLUGINCORE_API PluginInstance *StartPlugin();
  extern "C" PLUGINCORE_API void StopPlugin();
  合 肥 外 围 - 合 肥 哪 有 外 围 -薇芯【81343628】【81343628】【高端外围资源】【诚信合作,非诚勿扰!】可直接添加 !上面的StartPlugin就是动态库加载进来时候需要访问的符号,这个函数里面去启动这个插件,StopPlugin是卸载插件时需要调用的函数。
  这里用到了动态库的导入,关于动态库不同平台上有不同的扩展名以及加载函数,为了保持API的跨平台性,我这里简单的封装了动态库加载和卸载的过程,用typedef void* HLIB;表示动态库的句柄。下面这个类也呈现给读者,不妥的也给建议。

猜你喜欢

转载自www.cnblogs.com/zhaoyanchun/p/12784093.html