#include <lib/sconfig.h>
#include <lib/tl/linkedlist.h>
#include <lib/threads/mutex.h>
#include <lib/module/sharedobject.h>
#include <gmodule/gmodule.h>
Include dependency graph for pool.h:
This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Classes | |
class | ModulePool |
Does loading and unloading of modules. Kindof "manager". More... | |
Defines | |
#define | _LIB_MODULE_POOL_H_ 1 |
Next, any thread can go loading modules by calling ModulePool::load() and supply the name of the shared object / module / dynamically linked library to be loaded. This will return a class SharedObject which represents the shared object.
The class SharedObject is "C++-safe" and uses reference counting. You should never use pointers to it but instead the class itself: Therefore, you need not worry about unloading shared objects since they are automaticall unloded once the shared object is no longer used (no ModuleSymbol referring to the shared object is existing any longer and no instance of SharedObject).
Shared objects contain symbols (functions, variables, ...) which can be looked up and then (in case of functions) be executed. Make sure you properly cast a function pointer from a shared object since from looking at the shared object's symbol name, we do not know the argument list.
Here is an example on how it is meant to work:
#include <lib/module/pool.h> #include <lib/module/symbol.h> int main() { if(ModulePool::init()) { fprintf(stderr,"Modules not supported.\n"); exit(1); } // Start your threads... // One of them calls "foo" ModulePool::cleanup(); return(0); } void foo() { ModuleSymbol sym; { // We need to load a module: SharedObject so=ModulePool::load("mymodule.so"); if(so->error()) // Note: "pointer feeling" :) [overloaded operator!] { fprintf(stderr,"Failed to load module: %s\n",so->error()); return; } // Loading was success. Get a symbol: ModuleSymbol sym_bar=so->lookup("bar"); if(!sym_bar) // equiv: if(!sym_bar.ptr()) { fprintf(stderr,"OOPS: Symbol bar not present in module.\n"); return; } // You can use ModuleSymbol and SharedObject just like any other // safe type (like PODs e.g.); just do not use pointers on them: sym=sym_bar; // SharedObject "so" and ModuleSymbol "sym_bar" get destroyed but // module will NOT be unloaded here since "sym" still holds a // reference. } typedef int (*bar_fptr)(double); // Call the function "bar" (which is provided by the module / shared // object): (*(bar_fptr)sym.ptr())( 3.14 ); // Or, we can use the more convenient ModuleFunction class which is // also a safe type and can be used like a function pointer: ModuleFunction<int(*)(double)> bar=sym; // or ModuleFunction<bar_fptr> ... (*bar)( 3.14 ); // This will unload the module as we explicitly delete the last reference // to it. sym=ModuleSymbol(); // NOTE that you can explicitly de-reference a shared object (i.e. // make it a NULL reference) using: // SharedObject::deref(), i.e. so.deref() above (NOT so->deref()) // or by assigning a NULL ref: // so = SharedObject(); (with so from above) }
Definition in file pool.h.
|
|