summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-06-05 20:04:28 +0000
committerMike Buland <eichlan@xagasoft.com>2006-06-05 20:04:28 +0000
commitfa7df2006c0e241314212644c1ec5e362220defd (patch)
tree9befeb1b72869a4989fdf155414e5d0800aa9ea5
parent390a5110c6dfe439dddb5f7d2bb6f615c1d336ad (diff)
downloadlibbu++-fa7df2006c0e241314212644c1ec5e362220defd.tar.gz
libbu++-fa7df2006c0e241314212644c1ec5e362220defd.tar.bz2
libbu++-fa7df2006c0e241314212644c1ec5e362220defd.tar.xz
libbu++-fa7df2006c0e241314212644c1ec5e362220defd.zip
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...
-rw-r--r--Makefile2
-rw-r--r--src/plugger.cpp1
-rw-r--r--src/plugger.h124
-rw-r--r--src/plugin.cpp10
-rw-r--r--src/plugin.h14
-rw-r--r--src/test/params.cpp3
-rw-r--r--src/test/plugin/main.cpp14
7 files changed, 166 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 8c054c7..31a2df7 100644
--- a/Makefile
+++ b/Makefile
@@ -42,7 +42,7 @@ $(LIB): $(OBJS)
42 42
43$(TESTS): $(ATOBJS) $(LIB) 43$(TESTS): $(ATOBJS) $(LIB)
44 echo "$(TXTLNK)$@" 44 echo "$(TXTLNK)$@"
45 g++ $(LDFLAGS) -ggdb $(filter %$(patsubst tests/%,%,$@).o, $(TOBJS) ) $(patsubst %.cpp,%.o,$(wildcard $(filter %$(patsubst tests/%,%,$@), $(TDIRS))/*.cpp)) -L. -lbu++ -o $@ 45 g++ $(LDFLAGS) -ggdb $(filter %$(patsubst tests/%,%,$@).o, $(TOBJS) ) $(patsubst %.cpp,%.o,$(wildcard $(filter %$(patsubst tests/%,%,$@), $(TDIRS))/*.cpp)) -L. -lbu++ -ldl -o $@
46 46
47$(UNIT): $(USRCS) $(LIB) 47$(UNIT): $(USRCS) $(LIB)
48 echo "$(TXTLNK)$@" 48 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 @@
1#ifndef PLUGGER_H
2#define PLUGGER_H
3
4#include "hashtable.h"
5#include "list"
6#include "hashfunctionstring.h"
7#include "hashfunctionint.h"
8#include "dlfcn.h"
9
10typedef struct PluginInfo
11{
12 const char *sID;
13 const char *sAuthor;
14 unsigned short nVersion;
15 unsigned short nRevision;
16 class Plugin *(*createPlugin)();
17 void (*destroyPlugin)( class Plugin * );
18} PluginInfo;
19
20#define PluginInterface( classname, name, ver, rev ) \
21extern "C" { \
22 class Plugin *create ##classname() \
23 { \
24 return new classname(); \
25 } \
26 void destroy ##classname( class Plugin *pCls ) \
27 { \
28 delete pCls; \
29 } \
30 PluginInfo classname = { #classname, name, ver, rev, \
31 create ##classname, destroy ##classname }; \
32}
33
34typedef struct PluginReg
35{
36 bool bBuiltin;
37 void *dlHandle;
38 PluginInfo *pInfo;
39} PluginReg;
40
41template<class T>
42class Plugger
43{
44public:
45 Plugger() :
46 hPlugin( new HashFunctionString(), 11 ),
47 hObj( new HashFunctionInt(), 11 )
48 {
49 }
50
51 virtual ~Plugger()
52 {
53 std::list<PluginReg *>::iterator i;
54 for( i = lPlugin.begin(); i != lPlugin.end(); i++ )
55 {
56 if( (*i)->bBuiltin == false )
57 {
58 dlclose( (*i)->dlHandle );
59 }
60 delete (*i);
61 }
62 }
63
64 void registerBuiltinPlugin( PluginInfo *pInfo )
65 {
66 PluginReg *pReg = new PluginReg;
67 pReg->bBuiltin = true;
68 pReg->pInfo = pInfo;
69 lPlugin.insert( lPlugin.end(), pReg );
70 hPlugin.insert( pInfo->sID, pReg );
71 }
72
73 void registerExternalPlugin( const char *sFName, const char *sPluginName )
74 {
75 PluginReg *pReg = new PluginReg;
76 pReg->bBuiltin = false;
77 pReg->dlHandle = dlopen( sFName, RTLD_NOW );
78 if( pReg->dlHandle == NULL )
79 {
80 printf("***ERROR: %s\n\n", dlerror() );
81 exit( 105 );
82 }
83 pReg->pInfo = (PluginInfo *)dlsym( pReg->dlHandle, sPluginName );
84 if( pReg->pInfo == NULL )
85 {
86 printf("***ERROR: %s\n\n", dlerror() );
87 exit( 106 );
88 }
89 hPlugin.insert( pReg->pInfo->sID, pReg );
90 lPlugin.insert( lPlugin.end(), pReg );
91 }
92
93 T *instantiate( const char *lpName )
94 {
95 PluginReg *pReg = (PluginReg *)hPlugin[lpName];
96 if( pReg == NULL )
97 return NULL;
98
99 T *p = pReg->pInfo->createPlugin();
100 hObj.insert( p, pReg );
101 printf("pReg: %08X, pPlug: %08X\n", pReg, p );
102
103 return p;
104 }
105
106 void destroy( T *pPlug )
107 {
108 PluginReg *pReg = (PluginReg *)hObj[pPlug];
109 printf("pReg: %08X, pPlug: %08X\n", pReg, pPlug );
110 if( pReg == NULL )
111 return;
112
113 pReg->pInfo->destroyPlugin( pPlug );
114
115 hObj.del( pPlug );
116 }
117
118private:
119 std::list<PluginReg *> lPlugin;
120 HashTable hPlugin;
121 HashTable hObj;
122};
123
124#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 @@
1#include "plugin.h"
2
3Plugin::Plugin()
4{
5}
6
7Plugin::~Plugin()
8{
9}
10
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 @@
1#ifndef PLUGIN_H
2#define PLUGIN_H
3
4class Plugin
5{
6public:
7 Plugin();
8 virtual ~Plugin();
9
10private:
11
12};
13
14#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[] )
16 "Set the bool off." }, 16 "Set the bool off." },
17 { "char", 'c', PPROC_CHAR, NULL, &cChar, 17 { "char", 'c', PPROC_CHAR, NULL, &cChar,
18 "Set the char." }, 18 "Set the char." },
19 { NULL, '\0', 0, NULL, NULL, NULL } 19 { NULL, '\0',0, NULL, NULL,
20 NULL }
20 }; 21 };
21 22
22 processParams( argc, argv, table ); 23 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 @@
1#include "plugger.h"
2#include "plugin.h"
3
4int main()
5{
6 Plugger<Plugin> p;
7
8 p.registerExternalPlugin( "./guy.so", "Guy" );
9
10 Plugin *t = p.instantiate( "Guy" );
11
12 p.destroy( t );
13}
14