1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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, baseclass, name, ver, rev ) \
extern "C" { \
class baseclass *create ##classname() \
{ \
return new classname(); \
} \
void destroy ##classname( class baseclass *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 T>
class Plugger
{
public:
Plugger() :
hPlugin( new HashFunctionString(), 11 ),
hObj( new HashFunctionInt(), 11 )
{
}
virtual ~Plugger()
{
std::list<PluginReg *>::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<PluginReg *> lPlugin;
HashTable hPlugin;
HashTable hObj;
};
#endif
|