From c5dca40260e9dd004f72178f1702d92fcbafc590 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Fri, 23 Aug 2019 17:11:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8F=92=E4=BB=B6=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/hgl/plugin/ExternalPlugIn.h | 43 +++++++++++++++++++++ inc/hgl/plugin/PlugIn.h | 46 ++++++++++++++++++++++ inc/hgl/plugin/PlugInInterface.h | 34 +++++++++++++++++ inc/hgl/plugin/PlugInManage.h | 65 ++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 11 +++--- src/PlugIn/ExternalPlugIn.cpp | 64 +++++++++++++++++++++++++++++++ 6 files changed, 258 insertions(+), 5 deletions(-) create mode 100644 inc/hgl/plugin/ExternalPlugIn.h create mode 100644 inc/hgl/plugin/PlugIn.h create mode 100644 inc/hgl/plugin/PlugInInterface.h create mode 100644 inc/hgl/plugin/PlugInManage.h create mode 100644 src/PlugIn/ExternalPlugIn.cpp diff --git a/inc/hgl/plugin/ExternalPlugIn.h b/inc/hgl/plugin/ExternalPlugIn.h new file mode 100644 index 0000000..acd6c19 --- /dev/null +++ b/inc/hgl/plugin/ExternalPlugIn.h @@ -0,0 +1,43 @@ +#ifndef HGL_EXTERNAL_PLUG_IN_INCLUDE +#define HGL_EXTERNAL_PLUG_IN_INCLUDE + +#include +#include +namespace hgl +{ + /** + * 外部插件状态 + */ + enum class PlugInStatus + { + NONE, ///<无此插件 + LOAD_FAILED, ///<加载失败 + NO_LOAD, ///<可用未加载 + COMPLETE, ///<成功加载可用 + };//enum class PlugInStatus + + /** + * 外部插件 + */ + class ExternalPlugIn:public PlugIn + { + PlugInStatus status; + + OSString filename; ///<插件对应的真实文件系统名称 + + ExternalModule *pi_module; + + public: + + PlugInStatus GetStatus()const{return status;} + + public: + + ExternalPlugIn(); + virtual ~ExternalPlugIn(); + + void Free(); ///<释放插件文件 + bool Load(const UTF16String &,const OSString &); ///<加载插件 + };//class ExternalPlugIn:public PlugIn +}//namespace hgl +#endif//HGL_EXTERNAL_PLUG_IN_INCLUDE diff --git a/inc/hgl/plugin/PlugIn.h b/inc/hgl/plugin/PlugIn.h new file mode 100644 index 0000000..fb025a4 --- /dev/null +++ b/inc/hgl/plugin/PlugIn.h @@ -0,0 +1,46 @@ +#ifndef HGL_PLUGIN_INCLUDE +#define HGL_PLUGIN_INCLUDE + +#include +#include +namespace hgl +{ + /** + * 插件基类 + */ + class PlugIn ///插件 + { + protected: + + uint ref_count; + + uint ver; + UTF16String name; + UTF16String intro; + + OSString filename; ///<插件文件名 + + PlugInInterface *plugin_interface; + + public: + + const uint GetVersion ()const{return ver;} ///<取得插件版本 + const UTF16String & GetIntro ()const{return intro;} ///<取得插件介绍 + const UTF16String & GetName ()const{return name;} ///<取得插件名称 + + public: + + PlugIn() + { + ref_count=0; + ver=0; + plugin_interface=nullptr; + } + + virtual ~PlugIn(); + + uint add_ref(){return ++ref_count;} + uint release_ref(){return --ref_count;} + };//class PlugIn +}//namespace hgl +#endif//HGL_PLUGIN_INCLUDE diff --git a/inc/hgl/plugin/PlugInInterface.h b/inc/hgl/plugin/PlugInInterface.h new file mode 100644 index 0000000..ab86063 --- /dev/null +++ b/inc/hgl/plugin/PlugInInterface.h @@ -0,0 +1,34 @@ +#ifndef HGL_PLUG_IN_INTERFACE_INCLUDE +#define HGL_PLUG_IN_INTERFACE_INCLUDE + +#include +namespace hgl +{ + typedef void (*ClosePlugInPROC)(); ///<关闭插件 + + typedef uint32 (*GetPlugInVersionPROC)(); ///<取得插件版本号 + typedef u16char * (*GetPlugInIntroPROC)(); ///<取得插件介绍信息 + + typedef bool (*GetPlugInInterfacePROC)(uint32,void *); ///<取得插件接口 + typedef void (*SetPlugInInterfacePROC)(void *,void *); ///<设置插件接口 + + typedef bool (*LoadInterfaceByNamePROC)(const u16char *,uint32,void *); ///<取得接口 + typedef bool (*LoadInterfaceByIndexPROC)(uint32,uint32,void *); ///<取得接口 + + struct PlugInInterface + { + ClosePlugInPROC Close; + + GetPlugInVersionPROC GetVersion; + GetPlugInIntroPROC GetIntro; + + GetPlugInInterfacePROC GetInterface; + SetPlugInInterfacePROC SetInterface; + + LoadInterfaceByNamePROC LoadByName; + LoadInterfaceByIndexPROC LoadByIndex; + };//struct PlugInInterface + + typedef PlugInInterface *(*InitPlugInPROC)(); ///<初始化插件 +}//namespace hgl +#endif//HGL_PLUG_IN_INTERFACE_INCLUDE diff --git a/inc/hgl/plugin/PlugInManage.h b/inc/hgl/plugin/PlugInManage.h new file mode 100644 index 0000000..5255622 --- /dev/null +++ b/inc/hgl/plugin/PlugInManage.h @@ -0,0 +1,65 @@ +#ifndef HGL_PLUG_IN_MANAGE_INCLUDE +#define HGL_PLUG_IN_MANAGE_INCLUDE + +#include +#include +namespace hgl +{ + /** + * 插件管理 + */ + template class PlugInManage:public ResManage + { + OSString name; ///<插件类目名称(必须符合代码名称规则) + + public: + + PlugInManage(const OSString &n) + { + name=n; + } + + virtual ~PlugInManager()=default; + };//template class PlugInManage + + /** + * 插件注册模板 + */ + template class RegistryPlugInProxy + { + SharedPtr plugin; + + public: + + RegistryPlugInProxy() + { + plugin=new T; + } + + virtual ~RegistryPlugInProxy()=default; + + T *get(){return *plugin;} + };//template class RegistryPlugInProxy + + /* + 内部插件: + 如Log一类必须存在的插件,直接在代码中一块儿编译链接 + + 外部插件: + 如音频音频图片解码编码、压缩解压缩等根据需要加载释放,以独立的.dll/.so/.dylib文件形式存在 + + 除log console/log file外,其它所有插件可以是内部插件也可以是外部插件 + */ + +#ifndef __MAKE_PLUGIN__ //内部插件 + #define REGISTRY_PLUG_IN(name,classname) static RegistryPlugInProxy plugin_proxy_##classname; +#else //外部插件 + #define REGISTRY_PLUG_IN(name,classname) + static + extern "C" void registry_plugin_##name(void) + { + + } +#endif//__MAKE_PLUGIN__ +}//namespace hgl +#endif//HGL_PLUG_IN_MANAGE_INCLUDE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 525db22..b4c5e84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,12 +43,11 @@ SET(BASE_OTHER_SOURCE SOURCE_GROUP("Other" FILES ${BASE_OTHER_SOURCE}) -SET(BASE_PLUG_IN_SOURCE - PlugIn/ExternalModule.cpp -# PlugIn/PlugIn.cpp -) +file(GLOB BASE_PLUG_IN_HEADER ${CMCORE_ROOT_INCLUDE_PATH}/hgl/plugin/*.h) +file(GLOB BASE_PLUG_IN_SOURCE PlugIn/*.cpp) -SOURCE_GROUP("PlugIn" FILES ${BASE_PLUG_IN_SOURCE}) +SOURCE_GROUP("PlugIn\\Header Files" FILES ${BASE_PLUG_IN_HEADER}) +SOURCE_GROUP("PlugIn\\Source Files" FILES ${BASE_PLUG_IN_SOURCE}) add_library(CMCore STATIC #${SYSTEM_INFO_SOURCE} ${TYPE_TEMPLATE_HEADER} @@ -56,6 +55,8 @@ add_library(CMCore STATIC #${SYSTEM_INFO_SOURCE} ${BASE_IO_SOURCE} ${BASE_FILE_SYSTEM_SOURCE} ${BASE_OTHER_SOURCE} + + ${BASE_PLUG_IN_HEADER} ${BASE_PLUG_IN_SOURCE}) set_property(TARGET CMCore PROPERTY FOLDER "CM") diff --git a/src/PlugIn/ExternalPlugIn.cpp b/src/PlugIn/ExternalPlugIn.cpp new file mode 100644 index 0000000..c6d5eed --- /dev/null +++ b/src/PlugIn/ExternalPlugIn.cpp @@ -0,0 +1,64 @@ +#include +#include + +namespace hgl +{ + ExternalPlugIn::ExternalPlugIn() + { + status=PlugInStatus::NONE; + pi_module=nullptr; + } + + ExternalPlugIn::~ExternalPlugIn() + { + this->Free(); + } + + void ExternalPlugIn::Free() + { + if(!pi_module)return; + + plugin_interface->Close(); + + delete pi_module; + pi_module=nullptr; + + status=PlugInStatus::NO_LOAD; + } + + bool ExternalPlugIn::Load(const UTF16String &pn,const OSString &fn) + { + if(pi_module) + return(true); + + if(status==PlugInStatus::LOAD_FAILED) //过去是加载失败 + return(false); //直接拒绝加载 + + pi_module=LoadExternalModule(fn.c_str()); + + if(pi_module) + { + InitPlugInPROC init_proc=(InitPlugInPROC)pi_module->GetFunc("InitPlugIn"); + + if(init_proc!=nullptr) + { + plugin_interface=init_proc(); + + if(plugin_interface) + { + status=PlugInStatus::COMPLETE; + + name =pn; + filename=fn; + + ver =plugin_interface->GetVersion(); + intro =plugin_interface->GetIntro(); + return(true); + } + } + } + + status=PlugInStatus::LOAD_FAILED; + return(false); + } +}//namespace hgl