]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/dynamic.h
db46291c4b888f34acec0d1101ec725431c5383f
[user/henk/code/inspircd.git] / include / dynamic.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 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 /** This typedef represents the init_module function within each module.
18  * The init_module function is the only exported extern "C" declaration
19  * in any module file.
20  */
21 typedef void * (initfunc) (void);
22
23 #include "inspircd_config.h"
24
25 class InspIRCd;
26
27 /** The DLLManager class is able to load a module file by filename,
28  * and locate its init_module symbol.
29  */
30 class CoreExport DLLManager
31 {
32  public:
33         /** This constructor loads the module using dlopen()
34          * @param ServerInstance The creator class of this object
35          * @param fname The filename to load. This should be within
36          * the modules dir.
37          */
38         DLLManager(InspIRCd* ServerInstance, const char *fname);
39         virtual ~DLLManager();
40
41         /** Get a symbol using dynamic linking.
42          * @param v A function pointer, pointing at an init_module function
43          * @param sym_name The symbol name to find, usually "init_module"
44          * @return true if the symbol can be found, also the symbol will be put into v.
45          */
46         bool GetSymbol(void **v, const char *sym_name);
47
48         /** Get the last error from dlopen() or dlsym().
49          * @return The last error string, or NULL if no error has occured.
50          */
51         char* LastError() 
52         {
53                  return err;
54         }
55
56         /** The module handle.
57          * This is OS dependent, on POSIX platforms it is a pointer to a function
58          * pointer (yes, really!) and on windows it is a library handle.
59          */
60         void *h;
61
62  protected:
63
64         /** The last error string, or NULL
65          */
66         char *err;
67 };
68
69 /** This class is a specialized form of DLLManager designed to load InspIRCd modules.
70  * It's job is to call the init_module function and receive a factory pointer.
71  */
72 class CoreExport DLLFactoryBase : public DLLManager
73 {
74  public:
75         /** Default constructor.
76          * This constructor loads a module file by calling its DLLManager subclass constructor,
77          * then finds the symbol using DLLManager::GetSymbol(), and calls the symbol,
78          * obtaining a valid pointer to the init_module function
79          */
80         DLLFactoryBase(InspIRCd* Instance, const char *fname, const char *func_name = 0);
81
82         /** Default destructor.
83          */
84         virtual ~DLLFactoryBase();
85
86         /** A function pointer to the factory function.
87          */
88         void * (*factory_func)(void);   
89 };
90
91 /** This is the highest-level class of the DLLFactory system used to load InspIRCd modules.
92  * Its job is to finally call the init_module function and obtain a pointer to a ModuleFactory.
93  * This template is a container for ModuleFactory itself, so that it may 'plug' into ModuleFactory
94  * and provide module loading capabilities transparently.
95  */
96 template <class T> class CoreExport DLLFactory : public DLLFactoryBase
97 {
98  public:
99         /** Default constructor.
100          * This constructor passes its paramerers down through DLLFactoryBase and then DLLManager
101          * to load the module, then calls the factory function to retrieve a pointer to a ModuleFactory
102          * class. It is then down to the core to call the ModuleFactory::CreateModule() method and
103          * receive a Module* which it can insert into its module lists.
104          */
105         DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name=0) : DLLFactoryBase(Instance, fname, func_name)
106         {
107                 if (factory_func)
108                         factory = reinterpret_cast<T*>(factory_func());
109                 else
110                         factory = reinterpret_cast<T*>(-1);
111         }
112         
113         /** The destructor deletes the ModuleFactory pointer.
114          */
115         ~DLLFactory()
116         {
117                 if (factory)
118                         delete factory;
119         }
120
121         /** The ModuleFactory pointer.
122          */
123         T *factory;
124 };
125
126 #endif
127