]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/dynamic.h
6782820589c14db68e64132efe31c30f64a275a1
[user/henk/code/inspircd.git] / include / dynamic.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17
18 #ifndef __DLL_H
19 #define __DLL_H
20
21 /** This typedef represents the init_module function within each module.
22  * The init_module function is the only exported extern "C" declaration
23  * in any module file.
24  */
25 typedef void * (initfunc) (void);
26
27 #include "inspircd_config.h"
28
29 class InspIRCd;
30
31 /** The DLLManager class is able to load a module file by filename,
32  * and locate its init_module symbol.
33  */
34 class DLLManager
35 {
36  public:
37         /** This constructor loads the module using dlopen()
38          * @param ServerInstance The creator class of this object
39          * @param fname The filename to load. This should be within
40          * the modules dir.
41          */
42         DLLManager(InspIRCd* ServerInstance, const char *fname);
43         virtual ~DLLManager();
44
45
46 #ifdef STATIC_LINK
47         /** Get a symbol using static linking.
48          * @param v A static function pointer, pointing at an init_module function
49          * @param sym_name The symbol name to find, usually "init_module"
50          * @return True if the symbol can be found
51          */
52         bool GetSymbol(initfunc* &v, const char *sym_name);
53 #else
54         /** Get a symbol using dynamic linking.
55          * @param v A function pointer, pointing at an init_module function
56          * @param sym_name The symbol name to find, usually "init_module"
57          * @return true if the symbol can be found, also the symbol will be put into v.
58          */
59         bool GetSymbol(void **v, const char *sym_name);
60 #endif
61         /** Get the last error from dlopen() or dlsym().
62          * @return The last error string, or NULL if no error has occured
63          */
64         char* LastError() 
65         {
66                  return err;
67         }
68
69         /** The module handle
70          */
71         void *h;
72
73  protected:
74
75         /** The last error string, or NULL
76          */
77         char *err;
78 #ifdef STATIC_LINK
79
80         /** The module name
81          */
82         char staticname[1024];
83 #endif
84 };
85
86 /** This class is a specialized form of DLLManager designed to load InspIRCd modules.
87  * It's job is to call the init_module function and receive a factory pointer.
88  */
89 class DLLFactoryBase : public DLLManager
90 {
91  public:
92         /** Default constructor.
93          * This constructor loads a module file by calling its DLLManager subclass constructor,
94          * then finds the symbol using DLLManager::GetSymbol(), and calls the symbol,
95          * obtaining a valid pointer to the init_module function
96          */
97         DLLFactoryBase(InspIRCd* Instance, const char *fname, const char *func_name = 0);
98
99         /** Default destructor
100          */
101         virtual ~DLLFactoryBase();
102 #ifdef STATIC_LINK
103         /** A function pointer to the factory function
104          */
105         initfunc *factory_func;
106 #else
107         /** A function pointer to the factory function
108          */
109         void * (*factory_func)(void);   
110 #endif
111 };
112
113 /** This is the highest-level class of the DLLFactory system used to load InspIRCd modules.
114  * Its job is to finally call the init_module function and obtain a pointer to a ModuleFactory.
115  * This template is a container for ModuleFactory itself, so that it may 'plug' into ModuleFactory
116  * and provide module loading capabilities transparently.
117  */
118 template <class T> class DLLFactory : public DLLFactoryBase
119 {
120  public:
121         /** Default constructor.
122          * This constructor passes its paramerers down through DLLFactoryBase and then DLLManager
123          * to load the module, then calls the factory function to retrieve a pointer to a ModuleFactory
124          * class. It is then down to the core to call the ModuleFactory::CreateModule() method and
125          * receive a Module* which it can insert into its module lists.
126          */
127         DLLFactory(InspIRCd* Instance, const char *fname, const char *func_name=0) : DLLFactoryBase(Instance, fname, func_name)
128         {
129                 if (factory_func)
130                         factory = reinterpret_cast<T*>(factory_func());
131                 else
132                         factory = reinterpret_cast<T*>(-1);
133         }
134         
135         /** The destructor deletes the ModuleFactory pointer.
136          */
137         ~DLLFactory()
138         {
139                 if (factory)
140                         delete factory;
141         }
142
143         /** The ModuleFactory pointer.
144          */
145         T *factory;
146 };
147
148 #endif