]> git.saurik.com Git - wxWidgets.git/blob - include/wx/dynlib.h
forcefully disable wxUSE_STACKWALKER
[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/defs.h"
20
21 #if wxUSE_DYNLIB_CLASS
22
23 #include "wx/string.h"
24 #include "wx/dynarray.h"
25
26 #if defined(__WXPM__) || defined(__EMX__)
27 #include "wx/os2/private.h"
28 #endif
29
30 #ifdef __WXMSW__
31 #include "wx/msw/private.h"
32 #endif
33
34 #if defined(HAVE_DLERROR) && !defined(__EMX__)
35 #define wxHAVE_DYNLIB_ERROR
36 #endif
37
38 class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator;
39
40 // ----------------------------------------------------------------------------
41 // conditional compilation
42 // ----------------------------------------------------------------------------
43
44 // Note: WXPM/EMX has to be tested first, since we want to use
45 // native version, even if configure detected presence of DLOPEN.
46 #if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
47 typedef HMODULE wxDllType;
48 #elif defined(HAVE_DLOPEN)
49 #include <dlfcn.h>
50 typedef void *wxDllType;
51 #elif defined(HAVE_SHL_LOAD)
52 #include <dl.h>
53 typedef shl_t wxDllType;
54 #elif defined(__DARWIN__)
55 typedef void *wxDllType;
56 #elif defined(__WXMAC__)
57 #include <CodeFragments.h>
58 typedef CFragConnectionID wxDllType;
59 #else
60 #error "Dynamic Loading classes can't be compiled on this platform, sorry."
61 #endif
62
63 // ----------------------------------------------------------------------------
64 // constants
65 // ----------------------------------------------------------------------------
66
67 enum wxDLFlags
68 {
69 wxDL_LAZY = 0x00000001, // resolve undefined symbols at first use
70 // (only works on some Unix versions)
71 wxDL_NOW = 0x00000002, // resolve undefined symbols on load
72 // (default, always the case under Win32)
73 wxDL_GLOBAL = 0x00000004, // export extern symbols to subsequently
74 // loaded libs.
75 wxDL_VERBATIM = 0x00000008, // attempt to load the supplied library
76 // name without appending the usual dll
77 // filename extension.
78 wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded
79 // (only for wxPluginManager)
80
81 wxDL_DEFAULT = wxDL_NOW // default flags correspond to Win32
82 };
83
84 enum wxDynamicLibraryCategory
85 {
86 wxDL_LIBRARY, // standard library
87 wxDL_MODULE // loadable module/plugin
88 };
89
90 enum wxPluginCategory
91 {
92 wxDL_PLUGIN_GUI, // plugin that uses GUI classes
93 wxDL_PLUGIN_BASE // wxBase-only plugin
94 };
95
96 // ----------------------------------------------------------------------------
97 // macros
98 // ----------------------------------------------------------------------------
99
100 // when loading a function from a DLL you always have to cast the returned
101 // "void *" pointer to the correct type and, even more annoyingly, you have to
102 // repeat this type twice if you want to declare and define a function pointer
103 // all in one line
104 //
105 // this macro makes this slightly less painful by allowing you to specify the
106 // type only once, as the first parameter, and creating a variable of this type
107 // called "pfn<name>" initialized with the "name" from the "dynlib"
108 #define wxDYNLIB_FUNCTION(type, name, dynlib) \
109 type pfn ## name = (type)(dynlib).GetSymbol(_T(#name))
110
111 // ----------------------------------------------------------------------------
112 // wxDynamicLibraryDetails: contains details about a loaded wxDynamicLibrary
113 // ----------------------------------------------------------------------------
114
115 class WXDLLIMPEXP_BASE wxDynamicLibraryDetails
116 {
117 public:
118 // ctor, normally never used as these objects are only created by
119 // wxDynamicLibrary::ListLoaded()
120 wxDynamicLibraryDetails() { m_address = NULL; m_length = 0; }
121
122 // get the (base) name
123 wxString GetName() const { return m_name; }
124
125 // get the full path of this object
126 wxString GetPath() const { return m_path; }
127
128 // get the load address and the extent, return true if this information is
129 // available
130 bool GetAddress(void **addr, size_t *len) const
131 {
132 if ( !m_address )
133 return false;
134
135 if ( addr )
136 *addr = m_address;
137 if ( len )
138 *len = m_length;
139
140 return true;
141 }
142
143 // return the version of the DLL (may be empty if no version info)
144 wxString GetVersion() const
145 {
146 return m_version;
147 }
148
149 private:
150 wxString m_name,
151 m_path,
152 m_version;
153
154 void *m_address;
155 size_t m_length;
156
157 friend class wxDynamicLibraryDetailsCreator;
158 };
159
160 WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetails,
161 wxDynamicLibraryDetailsArray,
162 WXDLLIMPEXP_BASE);
163
164 // ----------------------------------------------------------------------------
165 // wxDynamicLibrary: represents a handle to a DLL/shared object
166 // ----------------------------------------------------------------------------
167
168 class WXDLLIMPEXP_BASE wxDynamicLibrary
169 {
170 public:
171 // return a valid handle for the main program itself or NULL if back
172 // linking is not supported by the current platform (e.g. Win32)
173 static wxDllType GetProgramHandle();
174
175 // return the platform standard DLL extension (with leading dot)
176 static const wxChar *GetDllExt() { return ms_dllext; }
177
178 wxDynamicLibrary() : m_handle(0) { }
179 wxDynamicLibrary(const wxString& libname, int flags = wxDL_DEFAULT)
180 : m_handle(0)
181 {
182 Load(libname, flags);
183 }
184
185 // NOTE: this class is (deliberately) not virtual, do not attempt
186 // to use it polymorphically.
187 ~wxDynamicLibrary() { Unload(); }
188
189 // return true if the library was loaded successfully
190 bool IsLoaded() const { return m_handle != 0; }
191
192 // load the library with the given name (full or not), return true if ok
193 bool Load(const wxString& libname, int flags = wxDL_DEFAULT);
194
195 // raw function for loading dynamic libs: always behaves as if
196 // wxDL_VERBATIM were specified and doesn't log error message if the
197 // library couldn't be loaded but simply returns NULL
198 static wxDllType RawLoad(const wxString& libname, int flags = wxDL_DEFAULT);
199
200 // detach the library object from its handle, i.e. prevent the object from
201 // unloading the library in its dtor -- the caller is now responsible for
202 // doing this
203 wxDllType Detach() { wxDllType h = m_handle; m_handle = 0; return h; }
204
205 // unload the given library handle (presumably returned by Detach() before)
206 static void Unload(wxDllType handle);
207
208 // unload the library, also done automatically in dtor
209 void Unload() { if ( IsLoaded() ) { Unload(m_handle); m_handle = 0; } }
210
211 // Return the raw handle from dlopen and friends.
212 wxDllType GetLibHandle() const { return m_handle; }
213
214 // check if the given symbol is present in the library, useful to verify if
215 // a loadable module is our plugin, for example, without provoking error
216 // messages from GetSymbol()
217 bool HasSymbol(const wxString& name) const
218 {
219 bool ok;
220 DoGetSymbol(name, &ok);
221 return ok;
222 }
223
224 // resolve a symbol in a loaded DLL, such as a variable or function name.
225 // 'name' is the (possibly mangled) name of the symbol. (use extern "C" to
226 // export unmangled names)
227 //
228 // Since it is perfectly valid for the returned symbol to actually be NULL,
229 // that is not always indication of an error. Pass and test the parameter
230 // 'success' for a true indication of success or failure to load the
231 // symbol.
232 //
233 // Returns a pointer to the symbol on success, or NULL if an error occurred
234 // or the symbol wasn't found.
235 void *GetSymbol(const wxString& name, bool *success = NULL) const;
236
237 // low-level version of GetSymbol()
238 static void *RawGetSymbol(wxDllType handle, const wxString& name);
239 void *RawGetSymbol(const wxString& name) const
240 {
241 #if defined (__WXPM__) || defined(__EMX__)
242 return GetSymbol(name);
243 #else
244 return RawGetSymbol(m_handle, name);
245 #endif
246 }
247
248 #ifdef __WXMSW__
249 // this function is useful for loading functions from the standard Windows
250 // DLLs: such functions have an 'A' (in ANSI build) or 'W' (in Unicode, or
251 // wide character build) suffix if they take string parameters
252 static void *RawGetSymbolAorW(wxDllType handle, const wxString& name)
253 {
254 return RawGetSymbol
255 (
256 handle,
257 name +
258 #if wxUSE_UNICODE
259 L'W'
260 #else
261 'A'
262 #endif
263 );
264 }
265
266 void *GetSymbolAorW(const wxString& name) const
267 {
268 return RawGetSymbolAorW(m_handle, name);
269 }
270 #endif // __WXMSW__
271
272 // return all modules/shared libraries in the address space of this process
273 //
274 // returns an empty array if not implemented or an error occurred
275 static wxDynamicLibraryDetailsArray ListLoaded();
276
277 // return platform-specific name of dynamic library with proper extension
278 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
279 static wxString CanonicalizeName(const wxString& name,
280 wxDynamicLibraryCategory cat = wxDL_LIBRARY);
281
282 // return name of wxWidgets plugin (adds compiler and version info
283 // to the filename):
284 static wxString
285 CanonicalizePluginName(const wxString& name,
286 wxPluginCategory cat = wxDL_PLUGIN_GUI);
287
288 // return plugin directory on platforms where it makes sense and empty
289 // string on others:
290 static wxString GetPluginsDirectory();
291
292
293 #if WXWIN_COMPATIBILITY_2_2
294 operator bool() const { return IsLoaded(); }
295 #endif
296
297 protected:
298 // common part of GetSymbol() and HasSymbol()
299 void *DoGetSymbol(const wxString& name, bool *success = 0) const;
300
301 #ifdef wxHAVE_DYNLIB_ERROR
302 // log the error after a dlxxx() function failure
303 static void Error();
304 #endif // wxHAVE_DYNLIB_ERROR
305
306
307 // platform specific shared lib suffix.
308 static const wxChar *ms_dllext;
309
310 // the handle to DLL or NULL
311 wxDllType m_handle;
312
313 // no copy ctor/assignment operators (or we'd try to unload the library
314 // twice)
315 DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
316 };
317
318
319 // ----------------------------------------------------------------------------
320 // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
321 // ----------------------------------------------------------------------------
322
323 #if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
324
325 /*
326 wxDllLoader is a class providing an interface similar to unix's dlopen().
327 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
328 DLLs and the resolving of symbols in them. There are no instances of this
329 class, it simply serves as a namespace for its static member functions.
330 */
331 class WXDLLIMPEXP_BASE wxDllLoader
332 {
333 public:
334 /*
335 This function loads the shared library libname into memory.
336
337 libname may be either the full path to the file or just the filename in
338 which case the library is searched for in all standard locations
339 (use GetDllExt() to construct the filename)
340
341 if success pointer is not NULL, it will be filled with true if everything
342 went ok and false otherwise
343 */
344 static wxDllType LoadLibrary(const wxString& name, bool *success = NULL);
345
346 /*
347 This function unloads the shared library previously loaded with
348 LoadLibrary
349 */
350 static void UnloadLibrary(wxDllType dll);
351
352 /*
353 This function returns a valid handle for the main program
354 itself or NULL if back linking is not supported by the current platform
355 (e.g. Win32).
356 */
357 static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
358
359 /*
360 This function resolves a symbol in a loaded DLL, such as a
361 variable or function name.
362
363 dllHandle Handle of the DLL, as returned by LoadDll().
364 name Name of the symbol.
365
366 Returns the pointer to the symbol or NULL on error.
367 */
368 static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
369
370 // return the standard DLL extension (with leading dot) for this platform
371 static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
372
373 private:
374
375 wxDllLoader(); // forbid construction of objects
376 };
377
378
379 // ----------------------------------------------------------------------------
380 // wxLibrary
381 // ----------------------------------------------------------------------------
382
383 #include "wx/hash.h"
384
385 class WXDLLIMPEXP_BASE wxLibrary : public wxObject
386 {
387 public:
388 wxLibrary(wxDllType handle);
389 virtual ~wxLibrary();
390
391 // Get a symbol from the dynamic library
392 void *GetSymbol(const wxString& symbname);
393
394 // Create the object whose classname is "name"
395 wxObject *CreateObject(const wxString& name);
396
397 protected:
398 void PrepareClasses(wxClassInfo *first);
399
400 wxDllType m_handle;
401
402 public:
403 wxHashTable classTable;
404 };
405
406 // ----------------------------------------------------------------------------
407 // wxLibraries
408 // ----------------------------------------------------------------------------
409
410 class WXDLLIMPEXP_BASE wxLibraries
411 {
412 public:
413 wxLibraries();
414 ~wxLibraries();
415
416 // caller is responsible for deleting the returned pointer if !NULL
417 wxLibrary *LoadLibrary(const wxString& basename);
418
419 wxObject *CreateObject(const wxString& name);
420
421 protected:
422 wxList m_loaded;
423 };
424
425 // ----------------------------------------------------------------------------
426 // Global variables
427 // ----------------------------------------------------------------------------
428
429 extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries;
430
431 #endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
432
433 // ----------------------------------------------------------------------------
434 // Interesting defines
435 // ----------------------------------------------------------------------------
436
437 #define WXDLL_ENTRY_FUNCTION() \
438 extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
439 const wxClassInfo *wxGetClassFirst() { \
440 return wxClassInfo::GetFirst(); \
441 }
442
443 #endif // wxUSE_DYNLIB_CLASS
444
445 #endif // _WX_DYNLIB_H__