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