From fa7df2006c0e241314212644c1ec5e362220defd Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 5 Jun 2006 20:04:28 +0000 Subject: Added a complete, general plugin manager system. There's a little bit of cleanup to do before it's totally ready, but it's looking good... --- Makefile | 2 +- src/plugger.cpp | 1 + src/plugger.h | 124 +++++++++++++++++++++++++++++++++++++++++++++++ src/plugin.cpp | 10 ++++ src/plugin.h | 14 ++++++ src/test/params.cpp | 3 +- src/test/plugin/main.cpp | 14 ++++++ 7 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 src/plugger.cpp create mode 100644 src/plugger.h create mode 100644 src/plugin.cpp create mode 100644 src/plugin.h create mode 100644 src/test/plugin/main.cpp diff --git a/Makefile b/Makefile index 8c054c7..31a2df7 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ $(LIB): $(OBJS) $(TESTS): $(ATOBJS) $(LIB) echo "$(TXTLNK)$@" - g++ $(LDFLAGS) -ggdb $(filter %$(patsubst tests/%,%,$@).o, $(TOBJS) ) $(patsubst %.cpp,%.o,$(wildcard $(filter %$(patsubst tests/%,%,$@), $(TDIRS))/*.cpp)) -L. -lbu++ -o $@ + g++ $(LDFLAGS) -ggdb $(filter %$(patsubst tests/%,%,$@).o, $(TOBJS) ) $(patsubst %.cpp,%.o,$(wildcard $(filter %$(patsubst tests/%,%,$@), $(TDIRS))/*.cpp)) -L. -lbu++ -ldl -o $@ $(UNIT): $(USRCS) $(LIB) echo "$(TXTLNK)$@" diff --git a/src/plugger.cpp b/src/plugger.cpp new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/plugger.cpp @@ -0,0 +1 @@ + diff --git a/src/plugger.h b/src/plugger.h new file mode 100644 index 0000000..2cf224e --- /dev/null +++ b/src/plugger.h @@ -0,0 +1,124 @@ +#ifndef PLUGGER_H +#define PLUGGER_H + +#include "hashtable.h" +#include "list" +#include "hashfunctionstring.h" +#include "hashfunctionint.h" +#include "dlfcn.h" + +typedef struct PluginInfo +{ + const char *sID; + const char *sAuthor; + unsigned short nVersion; + unsigned short nRevision; + class Plugin *(*createPlugin)(); + void (*destroyPlugin)( class Plugin * ); +} PluginInfo; + +#define PluginInterface( classname, name, ver, rev ) \ +extern "C" { \ + class Plugin *create ##classname() \ + { \ + return new classname(); \ + } \ + void destroy ##classname( class Plugin *pCls ) \ + { \ + delete pCls; \ + } \ + PluginInfo classname = { #classname, name, ver, rev, \ + create ##classname, destroy ##classname }; \ +} + +typedef struct PluginReg +{ + bool bBuiltin; + void *dlHandle; + PluginInfo *pInfo; +} PluginReg; + +template +class Plugger +{ +public: + Plugger() : + hPlugin( new HashFunctionString(), 11 ), + hObj( new HashFunctionInt(), 11 ) + { + } + + virtual ~Plugger() + { + std::list::iterator i; + for( i = lPlugin.begin(); i != lPlugin.end(); i++ ) + { + if( (*i)->bBuiltin == false ) + { + dlclose( (*i)->dlHandle ); + } + delete (*i); + } + } + + void registerBuiltinPlugin( PluginInfo *pInfo ) + { + PluginReg *pReg = new PluginReg; + pReg->bBuiltin = true; + pReg->pInfo = pInfo; + lPlugin.insert( lPlugin.end(), pReg ); + hPlugin.insert( pInfo->sID, pReg ); + } + + void registerExternalPlugin( const char *sFName, const char *sPluginName ) + { + PluginReg *pReg = new PluginReg; + pReg->bBuiltin = false; + pReg->dlHandle = dlopen( sFName, RTLD_NOW ); + if( pReg->dlHandle == NULL ) + { + printf("***ERROR: %s\n\n", dlerror() ); + exit( 105 ); + } + pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName ); + if( pReg->pInfo == NULL ) + { + printf("***ERROR: %s\n\n", dlerror() ); + exit( 106 ); + } + hPlugin.insert( pReg->pInfo->sID, pReg ); + lPlugin.insert( lPlugin.end(), pReg ); + } + + T *instantiate( const char *lpName ) + { + PluginReg *pReg = (PluginReg *)hPlugin[lpName]; + if( pReg == NULL ) + return NULL; + + T *p = pReg->pInfo->createPlugin(); + hObj.insert( p, pReg ); + printf("pReg: %08X, pPlug: %08X\n", pReg, p ); + + return p; + } + + void destroy( T *pPlug ) + { + PluginReg *pReg = (PluginReg *)hObj[pPlug]; + printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug ); + if( pReg == NULL ) + return; + + pReg->pInfo->destroyPlugin( pPlug ); + + hObj.del( pPlug ); + } + +private: + std::list lPlugin; + HashTable hPlugin; + HashTable hObj; +}; + +#endif diff --git a/src/plugin.cpp b/src/plugin.cpp new file mode 100644 index 0000000..ea558fd --- /dev/null +++ b/src/plugin.cpp @@ -0,0 +1,10 @@ +#include "plugin.h" + +Plugin::Plugin() +{ +} + +Plugin::~Plugin() +{ +} + diff --git a/src/plugin.h b/src/plugin.h new file mode 100644 index 0000000..f726867 --- /dev/null +++ b/src/plugin.h @@ -0,0 +1,14 @@ +#ifndef PLUGIN_H +#define PLUGIN_H + +class Plugin +{ +public: + Plugin(); + virtual ~Plugin(); + +private: + +}; + +#endif diff --git a/src/test/params.cpp b/src/test/params.cpp index 7bd2c0c..bb62047 100644 --- a/src/test/params.cpp +++ b/src/test/params.cpp @@ -16,7 +16,8 @@ int main( int argc, char *argv[] ) "Set the bool off." }, { "char", 'c', PPROC_CHAR, NULL, &cChar, "Set the char." }, - { NULL, '\0', 0, NULL, NULL, NULL } + { NULL, '\0',0, NULL, NULL, + NULL } }; processParams( argc, argv, table ); diff --git a/src/test/plugin/main.cpp b/src/test/plugin/main.cpp new file mode 100644 index 0000000..51c8390 --- /dev/null +++ b/src/test/plugin/main.cpp @@ -0,0 +1,14 @@ +#include "plugger.h" +#include "plugin.h" + +int main() +{ + Plugger p; + + p.registerExternalPlugin( "./guy.so", "Guy" ); + + Plugin *t = p.instantiate( "Guy" ); + + p.destroy( t ); +} + -- cgit v1.2.3