/*! \file piplugin.h * \brief Plugin helpers */ /* PIP - Platform Independent Primitives Plugin helpers Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIPLUGIN_H #define PIPLUGIN_H #ifndef PIP_FREERTOS #include "pilibrary.h" #include "pistringlist.h" #ifdef DOXYGEN //! Declare plugin export functions, should be used before other PIP_PLUGIN_* macros //! \relatedalso PIPluginLoader #define PIP_PLUGIN //! Set user version to check it while loading //! \relatedalso PIPluginLoader #define PIP_PLUGIN_SET_USER_VERSION(version) //! Add pointer to future merge with plugin. Type is integer //! \relatedalso PIPluginLoader #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) //! Declare function to merge static sections. This is functions //! with 3 arguments: (int type, void * from, void * to). //! This function invoked first while loading plugin with //! "from" - plugin scope, "to" - application scope, and second //! (optionally) on \a PIPluginLoader::mergeStatic() method with //! "from" - application scope, "to" - plugin scope. So with macro //! you can merge application and plugin static data. //! \relatedalso PIPluginLoader #define PIP_PLUGIN_STATIC_SECTION_MERGE //! Mark method to export //! \relatedalso PIPluginLoader #define PIP_PLUGIN_EXPORT #else #ifdef WINDOWS # define PIP_PLUGIN_EXPORT __declspec(dllexport) #else # define PIP_PLUGIN_EXPORT #endif #define __PIP_PLUGIN_LOADER_VERSION_FUNC__ pip_loader_version #define __PIP_PLUGIN_PLUGIN_INFO_FUNC__ pip_plugin_info #define __PIP_PLUGIN_STATIC_MERGE_FUNC__ pip_merge_static #define __PIP_PLUGIN_LOADER_VERSION__ 1 #define PIP_PLUGIN_SET_USER_VERSION(v) \ STATIC_INITIALIZER_BEGIN \ PIPluginInfo::instance()->setUserVersion(v); \ STATIC_INITIALIZER_END #define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \ STATIC_INITIALIZER_BEGIN \ PIPluginInfo::instance()->setStaticSection(type, ptr); \ STATIC_INITIALIZER_END #define PIP_PLUGIN \ STATIC_INITIALIZER_BEGIN \ PIPluginInfo::instance()->enterPlugin(); \ STATIC_INITIALIZER_END \ extern "C" { \ PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() {return __PIP_PLUGIN_LOADER_VERSION__;} \ PIP_PLUGIN_EXPORT PIPluginInfo * __PIP_PLUGIN_PLUGIN_INFO_FUNC__() {return PIPluginInfo::instance();} \ } #define PIP_PLUGIN_STATIC_SECTION_MERGE \ extern "C" { \ PIP_PLUGIN_EXPORT void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to); \ } \ void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to) #endif class PIP_EXPORT PIPluginInfo { public: PIPluginInfo(); void setUserVersion(const PIString & v); void setStaticSection(int type, void * ptr); PIString userVersion(bool plugin) const; PIMap staticSections(bool plugin) const; void enterPlugin(); static PIPluginInfo * instance(); private: PIString user_version[2]; PIMap static_sections[2]; bool in_plugin; }; class PIP_EXPORT PIPluginLoader { public: typedef int(*FunctionLoaderVersion)(); typedef PIPluginInfo*(*FunctionPluginInfo)(); typedef void(*FunctionStaticMerge)(int, void *, void *); //! Contruscts loader with filename "name" PIPluginLoader(const PIString & name = PIString()); //! Destructor ~PIPluginLoader(); //! Load plugin with base filename "name". Loader try prefix "lib" //! and suffix ".dll", ".so" or ".dylib", depends on platform bool load(const PIString & name); //! Unload plugin and free library void unload(); //! Returns if plugin is successfully loaded bool isLoaded() const; //! Returns loaded plugin library path PIString libPath(); //! Resolve symbol "name" from plugin library void * resolve(const char * name); //! Invoke plugin PIP_PLUGIN_STATIC_SECTION_MERGE function //! on every common type, with "from" - application scope, //! "to" - plugin scope void mergeStatic(); private: NO_COPY_CLASS(PIPluginLoader) PIString findLibrary(const PIString & path); static PIString libExtension(); PILibrary lib; FunctionLoaderVersion func_loader_version; FunctionPluginInfo func_plugin_info; FunctionStaticMerge func_static_merge; PIPluginInfo * plugin_info; bool loaded; }; #endif // PIP_FREERTOS #endif // PIPLUGIN_H