Compare commits
4 Commits
f9b497b5c0
...
cebe6f452f
| Author | SHA1 | Date | |
|---|---|---|---|
| cebe6f452f | |||
| bf1808f1c4 | |||
| b7aef483b7 | |||
| 7421f8c9a0 |
@@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||
project(pip)
|
||||
set(pip_MAJOR 2)
|
||||
set(pip_MINOR 10)
|
||||
set(pip_REVISION 0)
|
||||
set(pip_REVISION 1)
|
||||
set(pip_SUFFIX )
|
||||
set(pip_COMPANY SHS)
|
||||
set(pip_DOMAIN org.SHS)
|
||||
@@ -433,6 +433,9 @@ if (NOT CROSSTOOLS)
|
||||
|
||||
# Test program
|
||||
if(PIP_UTILS)
|
||||
#add_library(pip_plugin SHARED "test_plugin.h" "test_plugin.cpp")
|
||||
#target_link_libraries(pip_plugin pip)
|
||||
|
||||
add_executable(pip_test "main.cpp")
|
||||
target_link_libraries(pip_test pip pip_cloud)
|
||||
if (LUA_FOUND)
|
||||
|
||||
@@ -174,6 +174,13 @@ inline const char * getMemberType(const char * class_name, const char * member_n
|
||||
|
||||
PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name);
|
||||
|
||||
|
||||
template<typename T, typename std::enable_if< std::is_assignable<T&, const T&>::value, int>::type = 0>
|
||||
void serialize(PIByteArray & ret, const T & v) {ret << v;}
|
||||
|
||||
template<typename T, typename std::enable_if<!std::is_assignable<T&, const T&>::value, int>::type = 0>
|
||||
void serialize(PIByteArray & ret, const T & v) {}
|
||||
|
||||
}
|
||||
|
||||
class PIP_EXPORT __PICodeInfoInitializer__ {
|
||||
|
||||
@@ -79,6 +79,22 @@ PIString PIPVersion() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void piqsort(void * base, size_t num, size_t size, int (*compar)(const void *, const void *)) {
|
||||
qsort(base, num, size, compar);
|
||||
}
|
||||
|
||||
|
||||
void randomize() {
|
||||
srand(PISystemTime::current(true).nanoseconds);
|
||||
}
|
||||
|
||||
|
||||
int randomi() {
|
||||
return rand();
|
||||
}
|
||||
|
||||
|
||||
/*! \class PICout
|
||||
* \brief Class for formatted output similar std::cout
|
||||
*
|
||||
@@ -131,6 +147,9 @@ PIString PIPVersion() {
|
||||
* * packets extractor (\a PIPacketExtractor)
|
||||
* * binary log (\a PIBinaryLog)
|
||||
* * complex I/O point (\a PIConnection)
|
||||
* * Run-time libraries
|
||||
* * abstract (\a PILibrary)
|
||||
* * plugin (\a PIPluginLoader)
|
||||
* * connection quality diagnotic (\a PIDiagnostics)
|
||||
* * command-line arguments parser (\a PICLI)
|
||||
* * math evaluator (\a PIEvaluator)
|
||||
@@ -247,19 +266,3 @@ int main(int argc, char * argv[]) {
|
||||
/*! \page using_advanced Advanced using
|
||||
* Sorry, creativity crysis xD
|
||||
*/
|
||||
|
||||
|
||||
void piqsort(void * base, size_t num, size_t size, int (*compar)(const void *, const void *)) {
|
||||
qsort(base, num, size, compar);
|
||||
}
|
||||
|
||||
|
||||
void randomize() {
|
||||
srand(PISystemTime::current(true).nanoseconds);
|
||||
}
|
||||
|
||||
|
||||
int randomi() {
|
||||
return rand();
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,18 @@ public:
|
||||
//static PIMap<uint, __VariantFunctionsBase__*> & registered() {static PIMap<uint, __VariantFunctionsBase__*> ret; return ret;}
|
||||
};
|
||||
|
||||
/*
|
||||
template<class T, class Enable = void>
|
||||
class __VariantFunctions__: public __VariantFunctionsBase__ {
|
||||
public:
|
||||
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<T> ret; return &ret;}
|
||||
PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;}
|
||||
uint hash() const final {static uint ret = typeName().hash(); return ret;}
|
||||
};
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
class __VariantFunctions__: public __VariantFunctionsBase__ {
|
||||
class __VariantFunctions__/*<T, typename std::enable_if< std::is_assignable<T&, const T&>::value>::type>*/: public __VariantFunctionsBase__ {
|
||||
public:
|
||||
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<T> ret; return &ret;}
|
||||
PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;}
|
||||
@@ -58,6 +67,7 @@ public:
|
||||
//void fromData(void *& ptr, PIByteArray ba) final {ba >> *(T*)ptr;}
|
||||
};
|
||||
|
||||
|
||||
class PIVariantSimple {
|
||||
public:
|
||||
PIVariantSimple() {ptr = 0; f = 0;}
|
||||
@@ -129,6 +139,7 @@ public:
|
||||
private:
|
||||
template <typename T>
|
||||
bool isMyType() const {
|
||||
if (!f) return false;
|
||||
uint mh = f->hash(), th = __VariantFunctions__<T>().instance()->hash();
|
||||
if (mh == 0 || th == 0) return false;
|
||||
return mh == th;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/*! \file pilibrary.h
|
||||
* \brief Dynamic library
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Dynamic library
|
||||
|
||||
338
libs/main/system/piplugin.cpp
Normal file
338
libs/main/system/piplugin.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIP_FREERTOS
|
||||
|
||||
#include "piplugin.h"
|
||||
#include "pifile.h"
|
||||
#include "piincludes_p.h"
|
||||
|
||||
/*! \class PIPluginLoader
|
||||
* \brief Plugin loader
|
||||
*
|
||||
* \section PIPluginLoader_sec0 Synopsis
|
||||
* This class provides several macro to define plugin and %PIPluginLoader - class
|
||||
* to load and check plugin.
|
||||
*
|
||||
* \section PIPluginLoader_sec1 Plugin side
|
||||
* Plugin is a shared library that can be loaded in run-time.
|
||||
* This is only PIP_PLUGIN macro necessary to define plugin.
|
||||
* If you want to set and check some version, use macro
|
||||
* \a PIP_PLUGIN_SET_USER_VERSION(version). Also you can
|
||||
* define a function to merge static sections between application
|
||||
* and plugin with macro \a PIP_PLUGIN_STATIC_SECTION_MERGE. Before
|
||||
* merge, you should set pointers to that sections with macro
|
||||
* \a PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr).
|
||||
*
|
||||
* \section PIPluginLoader_sec2 Application side
|
||||
* Application should use class \a PIPluginLoader to load
|
||||
* plugin. Main function is \a load(PIString name).
|
||||
* "name" is base name of library, %PIPluginLoader
|
||||
* try to use sevaral names, <name>, lib<name> and
|
||||
* "dll", "so" and "dylib" extensions, depends on system.
|
||||
* For example:
|
||||
* \code
|
||||
* PIPluginLoader l;
|
||||
* l.load("foo");
|
||||
* \endcode
|
||||
* On Windows, try to open "foo", "libfoo", "foo.dll" and
|
||||
* "libfoo.dll".
|
||||
* If you using user version check, you should set it
|
||||
* with macro \a PIP_PLUGIN_SET_USER_VERSION(version).
|
||||
* When plugin is successfully loaded and checked,
|
||||
* you can load your custom cymbols with function
|
||||
* \a resolve(name), similar to PILibrary.
|
||||
* \note You should use PIP_PLUGIN_EXPORT and "export "C""
|
||||
* with functions you want to use with \a resolve(name)!
|
||||
*
|
||||
* \section PIPluginLoader_sec3 Static sections
|
||||
* Macro \a PIP_PLUGIN_STATIC_SECTION_MERGE defines function
|
||||
* with arguments (int type, void * from, void * to), so you
|
||||
* can leave this macro as declaration or define its body next:
|
||||
* \code
|
||||
* PIP_PLUGIN_STATIC_SECTION_MERGE() {
|
||||
* switch (type) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
* \note If you using singletones, remember that cpp-defined
|
||||
* singletones in shared libraries are single for whole application,
|
||||
* including plugins! But if you use h-defined singletones or
|
||||
* static linking, there are many objects in application and you
|
||||
* should merge their content with this macro.
|
||||
*
|
||||
* Anyway, if this is macro \a PIP_PLUGIN_STATIC_SECTION_MERGE, it
|
||||
* called once while loading plugin with "from" - plugin side
|
||||
* and "to" - application side, and second (optionally) on method
|
||||
* \a mergeStatic() with "from" - application side and "to" - plugin side.
|
||||
* First direction allow you to copy all defined static content from plugin
|
||||
* to application, and second - after loading all plugins (for example)
|
||||
* to copy static content from application (and all plugins) to plugin.
|
||||
*
|
||||
* \section PIPluginLoader_sec4 Examples
|
||||
* Simple plugin:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
*
|
||||
* PIP_PLUGIN
|
||||
*
|
||||
* extern "C" {
|
||||
* PIP_PLUGIN_EXPORT void myFunc() {
|
||||
* piCout << "Hello plugin!";
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Application:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
* int main() {
|
||||
* PIPluginLoader pl;
|
||||
* pl.load("your_lib");
|
||||
* if (pl.isLoaded()) {
|
||||
* typedef void(*MyFunc)();
|
||||
* MyFunc f = (MyFunc)pl.resolve("myFunc");
|
||||
* if (f) f();
|
||||
* }
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Complex plugin:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
*
|
||||
* PIStringList global_list;
|
||||
*
|
||||
* PIP_PLUGIN
|
||||
* PIP_PLUGIN_SET_USER_VERSION("1.0.0")
|
||||
* PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list)
|
||||
*
|
||||
* STATIC_INITIALIZER_BEGIN
|
||||
* global_list << "plugin_init";
|
||||
* STATIC_INITIALIZER_END
|
||||
*
|
||||
* PIP_PLUGIN_STATIC_SECTION_MERGE {
|
||||
* PIStringList * sfrom = (PIStringList*)from, * sto = (PIStringList*)to;
|
||||
* *sto << *sfrom;
|
||||
* sto->removeDuplicates();
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Application:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
*
|
||||
* PIStringList global_list;
|
||||
*
|
||||
* PIP_PLUGIN_SET_USER_VERSION("1.0.0");
|
||||
* PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list);
|
||||
*
|
||||
* int main() {
|
||||
* global_list << "app";
|
||||
* PIPluginLoader pl;
|
||||
* pl.load("your_lib");
|
||||
* pl.mergeStatic();
|
||||
* piCout << "list =" << global_list;
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
|
||||
#define STR_WF(s) #s
|
||||
#define STR(s) STR_WF(s)
|
||||
|
||||
|
||||
PIPluginInfo::PIPluginInfo() {
|
||||
in_plugin = false;
|
||||
}
|
||||
|
||||
|
||||
void PIPluginInfo::setUserVersion(const PIString & v) {
|
||||
user_version[in_plugin ? 1 : 0] = v;
|
||||
}
|
||||
|
||||
|
||||
void PIPluginInfo::setStaticSection(int type, void * ptr) {
|
||||
static_sections[in_plugin ? 1 : 0][type] = ptr;
|
||||
}
|
||||
|
||||
|
||||
PIString PIPluginInfo::userVersion(bool plugin) const {
|
||||
return user_version[plugin ? 1 : 0];
|
||||
}
|
||||
|
||||
|
||||
PIMap<int, void *> PIPluginInfo::staticSections(bool plugin) const {
|
||||
return static_sections[plugin ? 1 : 0];
|
||||
}
|
||||
|
||||
|
||||
void PIPluginInfo::enterPlugin() {
|
||||
in_plugin = true;
|
||||
}
|
||||
|
||||
|
||||
PIPluginInfo * PIPluginInfo::instance() {
|
||||
static PIPluginInfo ret;
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIPluginLoader::PIPluginLoader(const PIString & name) {
|
||||
func_loader_version = nullptr;
|
||||
func_plugin_info = nullptr;
|
||||
func_static_merge = nullptr;
|
||||
plugin_info = nullptr;
|
||||
loaded = false;
|
||||
if (!name.isEmpty())
|
||||
load(name);
|
||||
}
|
||||
|
||||
|
||||
PIPluginLoader::~PIPluginLoader() {
|
||||
lib.unload();
|
||||
}
|
||||
|
||||
|
||||
bool PIPluginLoader::load(const PIString & name) {
|
||||
unload();
|
||||
if (!lib.load(findLibrary(name))) return false;
|
||||
//piCout << "loading" << lib.path() << "...";
|
||||
func_loader_version = (FunctionLoaderVersion)lib.resolve(STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__));
|
||||
if (!func_loader_version) {
|
||||
piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_LOADER_VERSION_FUNC__);
|
||||
unload();
|
||||
return false;
|
||||
}
|
||||
if (__PIP_PLUGIN_LOADER_VERSION__ != func_loader_version()) {
|
||||
piCout << "Load plugin \"" << name << "\" error: invalid loader version: plugin" << __PIP_PLUGIN_LOADER_VERSION__ << "!=" << func_loader_version();
|
||||
unload();
|
||||
return false;
|
||||
}
|
||||
func_plugin_info = (FunctionPluginInfo)lib.resolve(STR(__PIP_PLUGIN_PLUGIN_INFO_FUNC__));
|
||||
if (!func_plugin_info) {
|
||||
piCout << "Load plugin \"" << name << "\" error: can`t find" << STR(__PIP_PLUGIN_PLUGIN_INFO_FUNC__);
|
||||
unload();
|
||||
return false;
|
||||
}
|
||||
plugin_info = func_plugin_info();
|
||||
if (!plugin_info) {
|
||||
piCout << "Load plugin \"" << name << "\" error: null PIPluginInfo";
|
||||
unload();
|
||||
return false;
|
||||
}
|
||||
if (PIPluginInfo::instance()->userVersion(false).size_s() > 1) {
|
||||
PIString pversion = plugin_info->userVersion(true), lversion = PIPluginInfo::instance()->userVersion(false);
|
||||
if (pversion != lversion) {
|
||||
piCout << "Load plugin \"" << name << "\" error: invalid user version: plugin" << pversion << "!=" << lversion;
|
||||
unload();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
func_static_merge = (FunctionStaticMerge)lib.resolve(STR(__PIP_PLUGIN_STATIC_MERGE_FUNC__));
|
||||
if (func_static_merge) {
|
||||
auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false);
|
||||
piCout << lss.keys() << pss.keys();
|
||||
|
||||
auto it = lss.makeIterator();
|
||||
while (it.next()) {
|
||||
if (!pss.contains(it.key()))
|
||||
continue;
|
||||
void * from = pss.value(it.key()), * to = it.value();
|
||||
if (from != to)
|
||||
func_static_merge(it.key(), from, to);
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PIPluginLoader::unload() {
|
||||
lib.unload();
|
||||
plugin_info = nullptr;
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
|
||||
bool PIPluginLoader::isLoaded() const {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
|
||||
PIString PIPluginLoader::libPath() {
|
||||
return lib.path();
|
||||
}
|
||||
|
||||
|
||||
void * PIPluginLoader::resolve(const char * name) {
|
||||
if (!loaded) return nullptr;
|
||||
return lib.resolve(name);
|
||||
}
|
||||
|
||||
|
||||
void PIPluginLoader::mergeStatic() {
|
||||
if (!loaded || !func_static_merge || !plugin_info) return;
|
||||
auto pss = plugin_info->staticSections(true), lss = PIPluginInfo::instance()->staticSections(false);
|
||||
auto it = lss.makeIterator();
|
||||
while (it.next()) {
|
||||
if (!pss.contains(it.key()))
|
||||
continue;
|
||||
void * from = it.value(), * to = pss.value(it.key());
|
||||
if (from != to)
|
||||
func_static_merge(it.key(), from, to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIString PIPluginLoader::findLibrary(const PIString & path) {
|
||||
static const PIStringList prefixes({"", "lib"});
|
||||
static const PIStringList suffixes({"", libExtension()});
|
||||
PIFile::FileInfo fi(path);
|
||||
PIString dir = fi.dir(), name = fi.name();
|
||||
piForeachC (PIString & p, prefixes) {
|
||||
piForeachC (PIString & s, suffixes) {
|
||||
PIString fn = dir + p + name + s;
|
||||
if (PIFile::isExists(fn))
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
return PIString();
|
||||
}
|
||||
|
||||
|
||||
PIString PIPluginLoader::libExtension() {
|
||||
return
|
||||
#ifdef WINDOWS
|
||||
".dll"
|
||||
#elif defined(MAC_OS)
|
||||
".dylib"
|
||||
#else
|
||||
".so"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
#endif // PIP_FREERTOS
|
||||
178
libs/main/system/piplugin.h
Normal file
178
libs/main/system/piplugin.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*! \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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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<int, void*> staticSections(bool plugin) const;
|
||||
void enterPlugin();
|
||||
|
||||
static PIPluginInfo * instance();
|
||||
|
||||
private:
|
||||
PIString user_version[2];
|
||||
PIMap<int, void*> 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
|
||||
@@ -325,7 +325,7 @@ void makeGetterValue(PIFile & f, const PICodeParser::Entity * e) {
|
||||
piForeachC (PICodeParser::Member & m, e->members) {
|
||||
if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public))
|
||||
continue;
|
||||
f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {ret << o->" << m.name << "; return ret;}\n";
|
||||
f << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n";
|
||||
}
|
||||
f << "\treturn ret;\n}\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user