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