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