added Unload(handle); updated the docs
[wxWidgets.git] / include / wx / dynlib.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/dynlib.h
3 // Purpose: Dynamic library loading classes
4 // Author: Guilhem Lavaux, Vadim Zeitlin, Vaclav Slavik
5 // Modified by:
6 // Created: 20/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_DYNLIB_H__
13 #define _WX_DYNLIB_H__
14
15 #if defined(__GNUG__) && !defined(__APPLE__)
16 # pragma interface "dynlib.h"
17 #endif
18
19 #include "wx/setup.h"
20
21 #if wxUSE_DYNLIB_CLASS
22
23 #include "wx/string.h"
24
25 // FIXME: can this go in private.h or something too??
26 #if defined(__WXPM__) || defined(__EMX__)
27 #define INCL_DOS
28 #include <os2.h>
29 #endif
30
31 #ifdef __WXMSW__
32 #include "wx/msw/private.h"
33 #endif
34
35 // ----------------------------------------------------------------------------
36 // conditional compilation
37 // ----------------------------------------------------------------------------
38
39 // Note: WXPM/EMX has to be tested first, since we want to use
40 // native version, even if configure detected presence of DLOPEN.
41 #if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
42 typedef HMODULE wxDllType;
43 #elif defined(HAVE_DLOPEN)
44 #include <dlfcn.h>
45 typedef void *wxDllType;
46 #elif defined(HAVE_SHL_LOAD)
47 #include <dl.h>
48 typedef shl_t wxDllType;
49 #elif defined(__DARWIN__)
50 typedef void *wxDllType;
51 #elif defined(__WXMAC__)
52 typedef CFragConnectionID wxDllType;
53 #else
54 #error "Dynamic Loading classes can't be compiled on this platform, sorry."
55 #endif
56
57 // ----------------------------------------------------------------------------
58 // constants
59 // ----------------------------------------------------------------------------
60
61 enum wxDLFlags
62 {
63 wxDL_LAZY = 0x00000001, // resolve undefined symbols at first use
64 wxDL_NOW = 0x00000002, // resolve undefined symbols on load
65 wxDL_GLOBAL = 0x00000004, // export extern symbols to subsequently
66 // loaded libs.
67 wxDL_VERBATIM = 0x00000008, // Attempt to load the supplied library
68 // name without appending the usual dll
69 // filename extension.
70
71 wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded
72
73 // FIXME: why? (VZ)
74 #ifdef __osf__
75 wxDL_DEFAULT = wxDL_LAZY
76 #else
77 wxDL_DEFAULT = wxDL_LAZY | wxDL_GLOBAL
78 #endif
79 };
80
81 enum wxDynamicLibraryCategory
82 {
83 wxDL_LIBRARY, // standard library
84 wxDL_MODULE // loadable module/plugin
85 };
86
87 enum wxPluginCategory
88 {
89 wxDL_PLUGIN_GUI, // plugin that uses GUI classes
90 wxDL_PLUGIN_BASE // wxBase-only plugin
91 };
92
93 // ----------------------------------------------------------------------------
94 // macros
95 // ----------------------------------------------------------------------------
96
97 // when loading a function from a DLL you always have to cast the returned
98 // "void *" pointer to the correct type and, even more annoyingly, you have to
99 // repeat this type twice if you want to declare and define a function pointer
100 // all in one line
101 //
102 // this macro makes this slightly less painful by allowing you to specify the
103 // type only once, as the first parameter, and creating a variable of this type
104 // called "pfn<name>" initialized with the "name" from the "dynlib"
105 #define wxDYNLIB_FUNCTION(type, name, dynlib) \
106 type pfn ## name = (type)(dynlib).GetSymbol(_T(#name))
107
108 // ---------------------------------------------------------------------------
109 // wxDynamicLibrary
110 // ---------------------------------------------------------------------------
111
112 class WXDLLIMPEXP_BASE wxDynamicLibrary
113 {
114 public:
115 // return a valid handle for the main program itself or NULL if back
116 // linking is not supported by the current platform (e.g. Win32)
117 static wxDllType GetProgramHandle();
118
119 // return the platform standard DLL extension (with leading dot)
120 static const wxChar *GetDllExt() { return ms_dllext; }
121
122 wxDynamicLibrary() : m_handle(0) { }
123 wxDynamicLibrary(const wxString& libname, int flags = wxDL_DEFAULT)
124 : m_handle(0)
125 {
126 Load(libname, flags);
127 }
128
129 // NOTE: this class is (deliberately) not virtual, do not attempt
130 // to use it polymorphically.
131 ~wxDynamicLibrary() { Unload(); }
132
133 // return TRUE if the library was loaded successfully
134 bool IsLoaded() const { return m_handle != 0; }
135
136 // load the library with the given name (full or not), return true if ok
137 bool Load(wxString libname, int flags = wxDL_DEFAULT);
138
139 // detach the library object from its handle, i.e. prevent the object from
140 // unloading the library in its dtor -- the caller is now responsible for
141 // doing this
142 wxDllType Detach() { wxDllType h = m_handle; m_handle = 0; return h; }
143
144 // unload the given library handle (presumably returned by Detach() before)
145 static void Unload(wxDllType handle);
146
147 // unload the library, also done automatically in dtor
148 void Unload() { if ( IsLoaded() ) { Unload(m_handle); m_handle = 0; } }
149
150 // Return the raw handle from dlopen and friends.
151 wxDllType GetLibHandle() const { return m_handle; }
152
153 // resolve a symbol in a loaded DLL, such as a variable or function name.
154 // 'name' is the (possibly mangled) name of the symbol. (use extern "C" to
155 // export unmangled names)
156 //
157 // Since it is perfectly valid for the returned symbol to actually be NULL,
158 // that is not always indication of an error. Pass and test the parameter
159 // 'success' for a true indication of success or failure to load the
160 // symbol.
161 //
162 // Returns a pointer to the symbol on success, or NULL if an error occurred
163 // or the symbol wasn't found.
164 void *GetSymbol(const wxString& name, bool *success = 0) const;
165
166
167 // return platform-specific name of dynamic library with proper extension
168 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
169 static wxString CanonicalizeName(const wxString& name,
170 wxDynamicLibraryCategory cat = wxDL_LIBRARY);
171
172 // return name of wxWindows plugin (adds compiler and version info
173 // to the filename):
174 static wxString
175 CanonicalizePluginName(const wxString& name,
176 wxPluginCategory cat = wxDL_PLUGIN_GUI);
177
178 // return plugin directory on platforms where it makes sense and empty
179 // string on others:
180 static wxString GetPluginsDirectory();
181
182
183 #if WXWIN_COMPATIBILITY_2_2
184 operator bool() const { return IsLoaded(); }
185 #endif
186
187 protected:
188 // platform specific shared lib suffix.
189 static const wxChar *ms_dllext;
190
191 // the handle to DLL or NULL
192 wxDllType m_handle;
193
194 // no copy ctor/assignment operators (or we'd try to unload the library
195 // twice)
196 DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
197 };
198
199
200 // ----------------------------------------------------------------------------
201 // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
202 // ----------------------------------------------------------------------------
203
204 #if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
205
206 /*
207 wxDllLoader is a class providing an interface similar to unix's dlopen().
208 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
209 DLLs and the resolving of symbols in them. There are no instances of this
210 class, it simply serves as a namespace for its static member functions.
211 */
212 class WXDLLIMPEXP_BASE wxDllLoader
213 {
214 public:
215 /*
216 This function loads the shared library libname into memory.
217
218 libname may be either the full path to the file or just the filename in
219 which case the library is searched for in all standard locations
220 (use GetDllExt() to construct the filename)
221
222 if success pointer is not NULL, it will be filled with TRUE if everything
223 went ok and FALSE otherwise
224 */
225 static wxDllType LoadLibrary(const wxString& name, bool *success = NULL);
226
227 /*
228 This function unloads the shared library previously loaded with
229 LoadLibrary
230 */
231 static void UnloadLibrary(wxDllType dll);
232
233 /*
234 This function returns a valid handle for the main program
235 itself or NULL if back linking is not supported by the current platform
236 (e.g. Win32).
237 */
238 static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
239
240 /*
241 This function resolves a symbol in a loaded DLL, such as a
242 variable or function name.
243
244 dllHandle Handle of the DLL, as returned by LoadDll().
245 name Name of the symbol.
246
247 Returns the pointer to the symbol or NULL on error.
248 */
249 static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
250
251 // return the standard DLL extension (with leading dot) for this platform
252 static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
253
254 private:
255
256 wxDllLoader(); // forbid construction of objects
257 };
258
259
260 // ----------------------------------------------------------------------------
261 // wxLibrary
262 // ----------------------------------------------------------------------------
263
264 #include "wx/hash.h"
265
266 class WXDLLIMPEXP_BASE wxLibrary : public wxObject
267 {
268 public:
269 wxLibrary(wxDllType handle);
270 virtual ~wxLibrary();
271
272 // Get a symbol from the dynamic library
273 void *GetSymbol(const wxString& symbname);
274
275 // Create the object whose classname is "name"
276 wxObject *CreateObject(const wxString& name);
277
278 protected:
279 void PrepareClasses(wxClassInfo *first);
280
281 wxDllType m_handle;
282
283 public:
284 wxHashTable classTable;
285 };
286
287 // ----------------------------------------------------------------------------
288 // wxLibraries
289 // ----------------------------------------------------------------------------
290
291 class WXDLLIMPEXP_BASE wxLibraries
292 {
293 public:
294 wxLibraries();
295 ~wxLibraries();
296
297 // caller is responsible for deleting the returned pointer if !NULL
298 wxLibrary *LoadLibrary(const wxString& basename);
299
300 wxObject *CreateObject(const wxString& name);
301
302 protected:
303 wxList m_loaded;
304 };
305
306 // ----------------------------------------------------------------------------
307 // Global variables
308 // ----------------------------------------------------------------------------
309
310 extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries;
311
312 #endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
313
314 // ----------------------------------------------------------------------------
315 // Interesting defines
316 // ----------------------------------------------------------------------------
317
318 #define WXDLL_ENTRY_FUNCTION() \
319 extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
320 const wxClassInfo *wxGetClassFirst() { \
321 return wxClassInfo::GetFirst(); \
322 }
323
324 #endif // wxUSE_DYNLIB_CLASS
325
326 #endif // _WX_DYNLIB_H__