added wxDynamicLibrary::HasSymbol()
[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 // check if the given symbol is present in the library, useful to verify if
155 // a loadable module is our plugin, for example, without provoking error
156 // messages from GetSymbol()
157 bool HasSymbol(const wxString& name) const
158 {
159 bool ok;
160 DoGetSymbol(name, &ok);
161 return ok;
162 }
163
164 // resolve a symbol in a loaded DLL, such as a variable or function name.
165 // 'name' is the (possibly mangled) name of the symbol. (use extern "C" to
166 // export unmangled names)
167 //
168 // Since it is perfectly valid for the returned symbol to actually be NULL,
169 // that is not always indication of an error. Pass and test the parameter
170 // 'success' for a true indication of success or failure to load the
171 // symbol.
172 //
173 // Returns a pointer to the symbol on success, or NULL if an error occurred
174 // or the symbol wasn't found.
175 void *GetSymbol(const wxString& name, bool *success = 0) const;
176
177
178 // return platform-specific name of dynamic library with proper extension
179 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
180 static wxString CanonicalizeName(const wxString& name,
181 wxDynamicLibraryCategory cat = wxDL_LIBRARY);
182
183 // return name of wxWidgets plugin (adds compiler and version info
184 // to the filename):
185 static wxString
186 CanonicalizePluginName(const wxString& name,
187 wxPluginCategory cat = wxDL_PLUGIN_GUI);
188
189 // return plugin directory on platforms where it makes sense and empty
190 // string on others:
191 static wxString GetPluginsDirectory();
192
193
194 #if WXWIN_COMPATIBILITY_2_2
195 operator bool() const { return IsLoaded(); }
196 #endif
197
198 protected:
199 // the real implementation of GetSymbol()
200 void *DoGetSymbol(const wxString& name, bool *success = 0) const;
201
202
203 // platform specific shared lib suffix.
204 static const wxChar *ms_dllext;
205
206 // the handle to DLL or NULL
207 wxDllType m_handle;
208
209 // no copy ctor/assignment operators (or we'd try to unload the library
210 // twice)
211 DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
212 };
213
214
215 // ----------------------------------------------------------------------------
216 // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
217 // ----------------------------------------------------------------------------
218
219 #if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
220
221 /*
222 wxDllLoader is a class providing an interface similar to unix's dlopen().
223 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
224 DLLs and the resolving of symbols in them. There are no instances of this
225 class, it simply serves as a namespace for its static member functions.
226 */
227 class WXDLLIMPEXP_BASE wxDllLoader
228 {
229 public:
230 /*
231 This function loads the shared library libname into memory.
232
233 libname may be either the full path to the file or just the filename in
234 which case the library is searched for in all standard locations
235 (use GetDllExt() to construct the filename)
236
237 if success pointer is not NULL, it will be filled with true if everything
238 went ok and false otherwise
239 */
240 static wxDllType LoadLibrary(const wxString& name, bool *success = NULL);
241
242 /*
243 This function unloads the shared library previously loaded with
244 LoadLibrary
245 */
246 static void UnloadLibrary(wxDllType dll);
247
248 /*
249 This function returns a valid handle for the main program
250 itself or NULL if back linking is not supported by the current platform
251 (e.g. Win32).
252 */
253 static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
254
255 /*
256 This function resolves a symbol in a loaded DLL, such as a
257 variable or function name.
258
259 dllHandle Handle of the DLL, as returned by LoadDll().
260 name Name of the symbol.
261
262 Returns the pointer to the symbol or NULL on error.
263 */
264 static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
265
266 // return the standard DLL extension (with leading dot) for this platform
267 static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
268
269 private:
270
271 wxDllLoader(); // forbid construction of objects
272 };
273
274
275 // ----------------------------------------------------------------------------
276 // wxLibrary
277 // ----------------------------------------------------------------------------
278
279 #include "wx/hash.h"
280
281 class WXDLLIMPEXP_BASE wxLibrary : public wxObject
282 {
283 public:
284 wxLibrary(wxDllType handle);
285 virtual ~wxLibrary();
286
287 // Get a symbol from the dynamic library
288 void *GetSymbol(const wxString& symbname);
289
290 // Create the object whose classname is "name"
291 wxObject *CreateObject(const wxString& name);
292
293 protected:
294 void PrepareClasses(wxClassInfo *first);
295
296 wxDllType m_handle;
297
298 public:
299 wxHashTable classTable;
300 };
301
302 // ----------------------------------------------------------------------------
303 // wxLibraries
304 // ----------------------------------------------------------------------------
305
306 class WXDLLIMPEXP_BASE wxLibraries
307 {
308 public:
309 wxLibraries();
310 ~wxLibraries();
311
312 // caller is responsible for deleting the returned pointer if !NULL
313 wxLibrary *LoadLibrary(const wxString& basename);
314
315 wxObject *CreateObject(const wxString& name);
316
317 protected:
318 wxList m_loaded;
319 };
320
321 // ----------------------------------------------------------------------------
322 // Global variables
323 // ----------------------------------------------------------------------------
324
325 extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries;
326
327 #endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
328
329 // ----------------------------------------------------------------------------
330 // Interesting defines
331 // ----------------------------------------------------------------------------
332
333 #define WXDLL_ENTRY_FUNCTION() \
334 extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
335 const wxClassInfo *wxGetClassFirst() { \
336 return wxClassInfo::GetFirst(); \
337 }
338
339 #endif // wxUSE_DYNLIB_CLASS
340
341 #endif // _WX_DYNLIB_H__