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