PIP 5.5.3
Platform-Independent Primitives
Public Types | Public Member Functions | Related Functions | List of all members
PIPluginLoader Class Reference

Plugin loader. More...

#include <piplugin.h>

Public Types

enum  Error {
  Unknown , NoError , NoSuchFile , LibraryLoadError ,
  MissingSymbols , InvalidLoaderVersion , InvalidUserVersion
}
 Possible load plugin error. More...
 

Public Member Functions

 PIPluginLoader (const PIString &name=PIString())
 Contruct loader with base filename "name" and call load() if "name" not empty.
 
 ~PIPluginLoader ()
 Destructor, unload library.
 
bool load (const PIString &name)
 Load plugin with base filename "name". More...
 
void unload ()
 Unload plugin and free library.
 
bool isLoaded () const
 Returns if plugin is successfully loaded.
 
Error lastError () const
 Returns error of last load() call.
 
PIString lastErrorText () const
 Returns error message of last load() call.
 
void setMessages (bool yes)
 Set if PIPluginLoader should print load messages, true by default.
 
bool isMessages () const
 Returns if PIPluginLoader should print load messages, true by default.
 
PIString libPath ()
 Returns loaded plugin library path.
 
void * resolve (const char *name)
 Obtain exported library method with name "symbol". More...
 
void mergeStatic ()
 Invoke plugin PIP_PLUGIN_STATIC_SECTION_MERGE. More...
 

Related Functions

(Note that these are not member functions.)

#define PIP_PLUGIN
 Declare plugin, should be used before other PIP_PLUGIN_* macros.
 
#define PIP_PLUGIN_SET_USER_VERSION(version)
 Set user version to check it while loading, "version" is quoted string.
 
#define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr)
 Add pointer to future merge with plugin. Type is integer.
 
#define PIP_PLUGIN_STATIC_SECTION_MERGE
 Declare function to merge static sections. More...
 
#define PIP_PLUGIN_EXPORT
 Mark method to export.
 

Detailed Description

Plugin loader.

Synopsis

This file provides several macro to define plugin and PIPluginLoader - class to load and check plugin.

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 PIP_PLUGIN_SET_USER_VERSION(version). Also you can define a function to merge static sections between application and plugin with macro PIP_PLUGIN_STATIC_SECTION_MERGE. Before merge, you should set pointers to that sections with macro PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr).

Application side

Application should use class PIPluginLoader to load plugin. Main function is 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:

l.load("foo");
Plugin loader.
Definition: piplugin.h:159
bool load(const PIString &name)
Load plugin with base filename "name".
Definition: piplugin.cpp:327

On Windows, try to open "foo", "libfoo", "foo.dll" and "libfoo.dll".
If you using user version check, you should set it with macro PIP_PLUGIN_SET_USER_VERSION(version). When plugin is successfully loaded and checked, you can load your custom symbols with function resolve(name), similar to PILibrary.

Note
You should use PIP_PLUGIN_EXPORT and C-linkage with functions you want to use with resolve(name)!

Static sections

Macro 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:

switch (type) {
...
}
}
#define PIP_PLUGIN_STATIC_SECTION_MERGE
Declare function to merge static sections.
Definition: piplugin.h:70
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 PIP_PLUGIN_STATIC_SECTION_MERGE, it called once while loading plugin with "from" - plugin side and "to" - application side, and second (optionally) on method 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 other plugins) to plugin.

Examples

Simple plugin:

#include <piplugin.h>
extern "C" {
PIP_PLUGIN_EXPORT void myFunc() {
piCout << "Hello plugin!";
}
}
#define PIP_PLUGIN_EXPORT
Mark method to export.
Definition: piplugin.h:75
#define PIP_PLUGIN
Declare plugin, should be used before other PIP_PLUGIN_* macros.
Definition: piplugin.h:40
#define piCout
Macro used for conditional (piDebug) output to PICout(StdOut)
Definition: picout.h:35
Plugin control.

Application:

#include <piplugin.h>
int main() {
pl.load("your_lib");
if (pl.isLoaded()) {
typedef void(*MyFunc)();
MyFunc f = (MyFunc)pl.resolve("myFunc");
if (f) f();
}
return 0;
}
void * resolve(const char *name)
Obtain exported library method with name "symbol".
Definition: piplugin.cpp:430
bool isLoaded() const
Returns if plugin is successfully loaded.
Definition: piplugin.cpp:400

Complex plugin:

#include <piplugin.h>
PIStringList global_list;
global_list << "plugin_init";
PIStringList * sfrom = (PIStringList*)from, * sto = (PIStringList*)to;
*sto << *sfrom;
}
#define PIP_PLUGIN_SET_USER_VERSION(version)
Set user version to check it while loading, "version" is quoted string.
Definition: piplugin.h:45
#define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr)
Add pointer to future merge with plugin. Type is integer.
Definition: piplugin.h:50
Based on PIDeque<PIString> strings list.
Definition: pistringlist.h:36
PIStringList & removeDuplicates()
Remove duplicated strings and returns reference to this.
Definition: pistringlist.cpp:75
#define STATIC_INITIALIZER_BEGIN
Macro to start static initializer.
Definition: pibase_macros.h:374
#define STATIC_INITIALIZER_END
Macro to end static initializer.
Definition: pibase_macros.h:379

Application:

#include <piplugin.h>
PIStringList global_list;
int main() {
global_list << "app";
pl.load("your_lib");
piCout << "list =" << global_list;
return 0;
}
void mergeStatic()
Invoke plugin PIP_PLUGIN_STATIC_SECTION_MERGE.
Definition: piplugin.cpp:443

Member Enumeration Documentation

◆ Error

Possible load plugin error.

Enumerator
Unknown 

No load() call yet

NoError 

No error

NoSuchFile 

Can`t find library file

LibraryLoadError 

System can`t load library

MissingSymbols 

Can`t find necessary symbols

InvalidLoaderVersion 

Internal version mismatch

InvalidUserVersion 

User version mismatch

Member Function Documentation

◆ load()

bool PIPluginLoader::load ( const PIString name)

Load plugin with base filename "name".

Loader try prefix "lib" and suffix ".dll", ".so" or ".dylib", depends on platform.

◆ resolve()

void * PIPluginLoader::resolve ( const char *  name)

Obtain exported library method with name "symbol".

See also
PILibrary::resolve()

◆ mergeStatic()

void PIPluginLoader::mergeStatic ( )

Invoke plugin PIP_PLUGIN_STATIC_SECTION_MERGE.

Call PIP_PLUGIN_STATIC_SECTION_MERGE function on every common type, with "from" - application scope, "to" - plugin scope

Friends And Related Function Documentation

◆ PIP_PLUGIN_STATIC_SECTION_MERGE

#define PIP_PLUGIN_STATIC_SECTION_MERGE
related

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 PIPluginLoader::mergeStatic() method with "from" - application scope, "to" - plugin scope. So with macro you can merge application and plugin static data.