]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/dynamic.h
Header update: 2007 -> 2008
[user/henk/code/inspircd.git] / include / dynamic.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef __DLL_H
15 #define __DLL_H
16
17 #include "inspircd_config.h"
18
19 /** The DLLManager class is able to load a module file by filename,
20  * and locate its init_module symbol.
21  */
22 class CoreExport DLLManager
23 {
24  protected:
25
26         /** The last error string, or NULL
27          */
28         char *err;
29  
30  public:
31         /** This constructor loads the module using dlopen()
32          * @param ServerInstance The creator class of this object
33          * @param fname The filename to load. This should be within
34          * the modules dir.
35          */
36         DLLManager(InspIRCd* ServerInstance, const char *fname);
37         virtual ~DLLManager();
38
39         /** Get a symbol using dynamic linking.
40          * @param v A function pointer, pointing at an init_module function
41          * @param sym_name The symbol name to find, usually "init_module"
42          * @return true if the symbol can be found, also the symbol will be put into v.
43          */
44         bool GetSymbol(void **v, const char *sym_name);
45
46         /** Get the last error from dlopen() or dlsym().
47          * @return The last error string, or NULL if no error has occured.
48          */
49         char* LastError() 
50         {
51                  return err;
52         }
53
54         /** The module handle.
55          * This is OS dependent, on POSIX platforms it is a pointer to a function
56          * pointer (yes, really!) and on windows it is a library handle.
57          */
58         void *h;
59 };
60
61 class CoreExport LoadModuleException : public CoreException
62 {
63  public:
64         /** This constructor can be used to specify an error message before throwing.
65          */
66         LoadModuleException(const std::string &message)
67         : CoreException(message, "the core")
68         {
69         }
70         
71         /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
72          * Actually no, it does nothing. Never mind.
73          * @throws Nothing!
74          */
75         virtual ~LoadModuleException() throw() {};
76 };
77
78 class CoreExport FindSymbolException : public CoreException
79 {
80  public:
81         /** This constructor can be used to specify an error message before throwing.
82          */
83         FindSymbolException(const std::string &message)
84         : CoreException(message, "the core")
85         {
86         }
87         
88         /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
89          * Actually no, it does nothing. Never mind.
90          * @throws Nothing!
91          */
92         virtual ~FindSymbolException() throw() {};
93 };
94
95 /** This is the highest-level class of the DLLFactory system used to load InspIRCd modules and commands.
96  * All the dirty mucking around with dl*() is done by DLLManager, all this does it put a pretty shell on
97  * it and make it nice to use to load modules and core commands. This class is quite specialised for these
98  * two uses and it may not be useful more generally -- use DLLManager directly for that.
99  */
100 template <typename ReturnType> class CoreExport DLLFactory : public DLLManager
101 {
102  protected:
103         /** This typedef represents the init_* function within each module or command.
104          * The init_module function is the only exported extern "C" declaration
105          * in any module file. In a cmd_*.cpp file the equivilant is init_command
106          */
107         typedef ReturnType * (initfunctype) (InspIRCd*);         
108  
109         /** Pointer to the init function.
110          */
111         initfunctype* init_func;
112
113         /** Instance pointer to be passed to init_*() when it is called.
114          */
115         InspIRCd* ServerInstance;
116  
117  public:
118         /** Default constructor.
119          * This constructor passes its paramerers down through DLLFactoryBase and then DLLManager
120          * to load the module, then calls the factory function to retrieve a pointer to a ModuleFactory
121          * class. It is then down to the core to call the ModuleFactory::CreateModule() method and
122          * receive a Module* which it can insert into its module lists.
123          */
124         DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name)
125         : DLLManager(Instance, fname), init_func(NULL), ServerInstance(Instance)
126         {       
127                 const char* error = LastError();
128                 
129                 if(!error)
130                 {
131                         if(!GetSymbol((void **)&init_func, func_name))
132                         {
133                                 throw FindSymbolException("Missing " + std::string(func_name) + "() entrypoint!");
134                         }
135                 }
136                 else
137                 {
138                         throw LoadModuleException(error);
139                 }
140         }
141         
142         ReturnType* CallInit()
143         {
144                 if(init_func)
145                 {
146                         return init_func(ServerInstance);
147                 }
148                 else
149                 {
150                         return NULL;
151                 }
152         }
153         
154         /** The destructor deletes the ModuleFactory pointer.
155          */
156         ~DLLFactory()
157         {
158         }
159 };
160
161 #endif