version 2.10.1

Documentation of PIPluginLoader
Remove PIVariantSimple ability to assign any type, leave only assignable
This commit is contained in:
2020-10-06 00:53:37 +03:00
parent b7aef483b7
commit bf1808f1c4
5 changed files with 179 additions and 23 deletions

View File

@@ -23,6 +23,140 @@
#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)
@@ -84,7 +218,7 @@ PIPluginLoader::~PIPluginLoader() {
bool PIPluginLoader::load(const PIString & name) {
unload();
if (!lib.load(findLibrary(name))) return false;
piCout << "loading" << lib.path() << "...";
//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__);
@@ -142,6 +276,11 @@ void PIPluginLoader::unload() {
}
bool PIPluginLoader::isLoaded() const {
return loaded;
}
PIString PIPluginLoader::libPath() {
return lib.path();
}