]> git.saurik.com Git - wxWidgets.git/blame - include/wx/dynlib.h
change superflous elif to else
[wxWidgets.git] / include / wx / dynlib.h
CommitLineData
7b0bfbb2 1/////////////////////////////////////////////////////////////////////////////
33a8563e
VZ
2// Name: wx/dynlib.h
3// Purpose: Dynamic library loading classes
4// Author: Guilhem Lavaux, Vadim Zeitlin, Vaclav Slavik
7b0bfbb2
VZ
5// Modified by:
6// Created: 20/07/98
7// RCS-ID: $Id$
33a8563e 8// Copyright: (c) 1998 Guilhem Lavaux
65571936 9// Licence: wxWindows licence
7b0bfbb2
VZ
10/////////////////////////////////////////////////////////////////////////////
11
34138703
JS
12#ifndef _WX_DYNLIB_H__
13#define _WX_DYNLIB_H__
7a4b9130 14
12028905 15#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
af49c4b8 16# pragma interface "dynlib.h"
7a4b9130
GL
17#endif
18
ed58dbea 19#include "wx/setup.h"
8a0d4cf6 20
1948bb32 21#if wxUSE_DYNLIB_CLASS
8a0d4cf6 22
ed58dbea 23#include "wx/string.h"
defbed48 24#include "wx/dynarray.h"
7a4b9130 25
1948bb32 26// FIXME: can this go in private.h or something too??
1a787c5d 27#if defined(__WXPM__) || defined(__EMX__)
1948bb32
VS
28#define INCL_DOS
29#include <os2.h>
30#endif
31
32#ifdef __WXMSW__
33#include "wx/msw/private.h"
34#endif
35
da55d064
VZ
36#if defined(HAVE_DLERROR) && !defined(__EMX__)
37 #define wxHAVE_DYNLIB_ERROR
38#endif
39
defbed48
VZ
40class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator;
41
1948bb32
VS
42// ----------------------------------------------------------------------------
43// conditional compilation
44// ----------------------------------------------------------------------------
45
4104ed92
VZ
46// Note: WXPM/EMX has to be tested first, since we want to use
47// native version, even if configure detected presence of DLOPEN.
1948bb32 48#if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
4104ed92 49 typedef HMODULE wxDllType;
1a787c5d 50#elif defined(HAVE_DLOPEN)
4104ed92
VZ
51 #include <dlfcn.h>
52 typedef void *wxDllType;
8a0d4cf6 53#elif defined(HAVE_SHL_LOAD)
4104ed92
VZ
54 #include <dl.h>
55 typedef shl_t wxDllType;
f11bdd03 56#elif defined(__DARWIN__)
4104ed92 57 typedef void *wxDllType;
7b0bfbb2 58#elif defined(__WXMAC__)
609533d5 59 #include <CodeFragments.h>
4104ed92 60 typedef CFragConnectionID wxDllType;
7b0bfbb2 61#else
4104ed92 62 #error "Dynamic Loading classes can't be compiled on this platform, sorry."
1948bb32
VS
63#endif
64
4104ed92
VZ
65// ----------------------------------------------------------------------------
66// constants
67// ----------------------------------------------------------------------------
1948bb32
VS
68
69enum 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
89enum wxDynamicLibraryCategory
90{
91 wxDL_LIBRARY, // standard library
13e51f3a 92 wxDL_MODULE // loadable module/plugin
1948bb32
VS
93};
94
95enum wxPluginCategory
96{
97 wxDL_PLUGIN_GUI, // plugin that uses GUI classes
13e51f3a 98 wxDL_PLUGIN_BASE // wxBase-only plugin
1948bb32
VS
99};
100
4104ed92
VZ
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
defbed48
VZ
116// ----------------------------------------------------------------------------
117// wxDynamicLibraryDetails: contains details about a loaded wxDynamicLibrary
118// ----------------------------------------------------------------------------
119
120class WXDLLIMPEXP_BASE wxDynamicLibraryDetails
121{
122public:
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
154private:
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
165WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetails,
166 wxDynamicLibraryDetailsArray,
167 WXDLLIMPEXP_BASE);
168
169// ----------------------------------------------------------------------------
170// wxDynamicLibrary: represents a handle to a DLL/shared object
171// ----------------------------------------------------------------------------
1948bb32
VS
172
173class WXDLLIMPEXP_BASE wxDynamicLibrary
174{
175public:
4104ed92
VZ
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)
1948bb32
VS
178 static wxDllType GetProgramHandle();
179
4104ed92 180 // return the platform standard DLL extension (with leading dot)
1948bb32
VS
181 static const wxChar *GetDllExt() { return ms_dllext; }
182
4104ed92 183 wxDynamicLibrary() : m_handle(0) { }
1948bb32
VS
184 wxDynamicLibrary(const wxString& libname, int flags = wxDL_DEFAULT)
185 : m_handle(0)
186 {
187 Load(libname, flags);
188 }
1948bb32 189
4104ed92
VZ
190 // NOTE: this class is (deliberately) not virtual, do not attempt
191 // to use it polymorphically.
192 ~wxDynamicLibrary() { Unload(); }
1948bb32 193
68379eaf 194 // return true if the library was loaded successfully
1948bb32
VS
195 bool IsLoaded() const { return m_handle != 0; }
196
4104ed92 197 // load the library with the given name (full or not), return true if ok
defbed48 198 bool Load(const wxString& libname, int flags = wxDL_DEFAULT);
1948bb32 199
defbed48
VZ
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
da55d064
VZ
203 static wxDllType RawLoad(const wxString& libname, int flags = wxDL_DEFAULT);
204
4104ed92
VZ
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
1948bb32
VS
208 wxDllType Detach() { wxDllType h = m_handle; m_handle = 0; return h; }
209
169948a0
VZ
210 // unload the given library handle (presumably returned by Detach() before)
211 static void Unload(wxDllType handle);
212
4104ed92 213 // unload the library, also done automatically in dtor
169948a0 214 void Unload() { if ( IsLoaded() ) { Unload(m_handle); m_handle = 0; } }
1948bb32 215
4104ed92 216 // Return the raw handle from dlopen and friends.
1948bb32
VS
217 wxDllType GetLibHandle() const { return m_handle; }
218
a018a119
VZ
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
4104ed92
VZ
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.
defbed48 240 void *GetSymbol(const wxString& name, bool *success = NULL) const;
1948bb32 241
defbed48
VZ
242 // low-level version of GetSymbol()
243 static void *RawGetSymbol(wxDllType handle, const wxString& name);
244 void *RawGetSymbol(const wxString& name) const
245 {
fd6c9428
SN
246#if defined (__WXPM__) || defined(__EMX__)
247 return GetSymbol(name);
248#else
defbed48 249 return RawGetSymbol(m_handle, name);
fd6c9428 250#endif
defbed48
VZ
251 }
252
253 // return all modules/shared libraries in the address space of this process
254 //
255 // returns an empty array if not implemented or an error occured
256 static wxDynamicLibraryDetailsArray ListLoaded();
0c32066b 257
1948bb32
VS
258 // return platform-specific name of dynamic library with proper extension
259 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
260 static wxString CanonicalizeName(const wxString& name,
261 wxDynamicLibraryCategory cat = wxDL_LIBRARY);
262
77ffb593 263 // return name of wxWidgets plugin (adds compiler and version info
1948bb32 264 // to the filename):
169948a0
VZ
265 static wxString
266 CanonicalizePluginName(const wxString& name,
267 wxPluginCategory cat = wxDL_PLUGIN_GUI);
1948bb32
VS
268
269 // return plugin directory on platforms where it makes sense and empty
270 // string on others:
271 static wxString GetPluginsDirectory();
272
1948bb32 273
4104ed92
VZ
274#if WXWIN_COMPATIBILITY_2_2
275 operator bool() const { return IsLoaded(); }
276#endif
1948bb32 277
4104ed92 278protected:
defbed48 279 // common part of GetSymbol() and HasSymbol()
a018a119
VZ
280 void *DoGetSymbol(const wxString& name, bool *success = 0) const;
281
da55d064
VZ
282#ifdef wxHAVE_DYNLIB_ERROR
283 // log the error after a dlxxx() function failure
284 static void Error();
285#endif // wxHAVE_DYNLIB_ERROR
286
a018a119 287
4104ed92 288 // platform specific shared lib suffix.
1948bb32
VS
289 static const wxChar *ms_dllext;
290
4104ed92 291 // the handle to DLL or NULL
1948bb32
VS
292 wxDllType m_handle;
293
4104ed92
VZ
294 // no copy ctor/assignment operators (or we'd try to unload the library
295 // twice)
1948bb32
VS
296 DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
297};
298
299
a585ca5c 300// ----------------------------------------------------------------------------
33a8563e 301// wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
a585ca5c 302// ----------------------------------------------------------------------------
3c1a88d8 303
1948bb32
VS
304#if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
305
33a8563e
VZ
306/*
307 wxDllLoader is a class providing an interface similar to unix's dlopen().
308 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
309 DLLs and the resolving of symbols in them. There are no instances of this
310 class, it simply serves as a namespace for its static member functions.
a585ca5c 311*/
bddd7a8d 312class WXDLLIMPEXP_BASE wxDllLoader
a585ca5c 313{
3c1a88d8 314public:
33a8563e
VZ
315 /*
316 This function loads the shared library libname into memory.
317
318 libname may be either the full path to the file or just the filename in
319 which case the library is searched for in all standard locations
320 (use GetDllExt() to construct the filename)
321
68379eaf
WS
322 if success pointer is not NULL, it will be filled with true if everything
323 went ok and false otherwise
33a8563e 324 */
1948bb32 325 static wxDllType LoadLibrary(const wxString& name, bool *success = NULL);
68379eaf 326
33a8563e
VZ
327 /*
328 This function unloads the shared library previously loaded with
329 LoadLibrary
3c1a88d8 330 */
3c1a88d8 331 static void UnloadLibrary(wxDllType dll);
33a8563e
VZ
332
333 /*
334 This function returns a valid handle for the main program
335 itself or NULL if back linking is not supported by the current platform
336 (e.g. Win32).
337 */
1948bb32 338 static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
33a8563e
VZ
339
340 /*
341 This function resolves a symbol in a loaded DLL, such as a
342 variable or function name.
343
344 dllHandle Handle of the DLL, as returned by LoadDll().
345 name Name of the symbol.
346
347 Returns the pointer to the symbol or NULL on error.
3c1a88d8 348 */
1948bb32 349 static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
3c1a88d8 350
f6bcfd97 351 // return the standard DLL extension (with leading dot) for this platform
1948bb32 352 static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
f6bcfd97 353
3c1a88d8 354private:
181b4068 355
1948bb32 356 wxDllLoader(); // forbid construction of objects
33a8563e 357};
181b4068 358
1948bb32 359
7b0bfbb2 360// ----------------------------------------------------------------------------
7a4b9130 361// wxLibrary
7b0bfbb2 362// ----------------------------------------------------------------------------
7a4b9130 363
1948bb32
VS
364#include "wx/hash.h"
365
bddd7a8d 366class WXDLLIMPEXP_BASE wxLibrary : public wxObject
7b0bfbb2 367{
7b0bfbb2 368public:
8a0d4cf6 369 wxLibrary(wxDllType handle);
33a8563e 370 virtual ~wxLibrary();
7a4b9130 371
7b0bfbb2
VZ
372 // Get a symbol from the dynamic library
373 void *GetSymbol(const wxString& symbname);
7a4b9130 374
7b0bfbb2
VZ
375 // Create the object whose classname is "name"
376 wxObject *CreateObject(const wxString& name);
7a4b9130 377
7b0bfbb2
VZ
378protected:
379 void PrepareClasses(wxClassInfo *first);
f4a8c29f 380
7b0bfbb2 381 wxDllType m_handle;
a585ca5c 382
33a8563e
VZ
383public:
384 wxHashTable classTable;
385};
a585ca5c 386
7b0bfbb2 387// ----------------------------------------------------------------------------
7a4b9130 388// wxLibraries
7b0bfbb2
VZ
389// ----------------------------------------------------------------------------
390
bddd7a8d 391class WXDLLIMPEXP_BASE wxLibraries
7b0bfbb2
VZ
392{
393public:
394 wxLibraries();
395 ~wxLibraries();
7a4b9130 396
7b0bfbb2
VZ
397 // caller is responsible for deleting the returned pointer if !NULL
398 wxLibrary *LoadLibrary(const wxString& basename);
7a4b9130 399
7b0bfbb2
VZ
400 wxObject *CreateObject(const wxString& name);
401
402protected:
403 wxList m_loaded;
7a4b9130
GL
404};
405
7b0bfbb2 406// ----------------------------------------------------------------------------
7a4b9130 407// Global variables
7b0bfbb2 408// ----------------------------------------------------------------------------
7a4b9130 409
bddd7a8d 410extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries;
7a4b9130 411
1948bb32
VS
412#endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
413
7b0bfbb2 414// ----------------------------------------------------------------------------
7a4b9130 415// Interesting defines
7b0bfbb2 416// ----------------------------------------------------------------------------
7a4b9130 417
f4a8c29f 418#define WXDLL_ENTRY_FUNCTION() \
ad8b3990 419extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
1b733817 420const wxClassInfo *wxGetClassFirst() { \
856d2e52 421 return wxClassInfo::GetFirst(); \
f4a8c29f 422}
7a4b9130 423
8a0d4cf6
VZ
424#endif // wxUSE_DYNLIB_CLASS
425
7b0bfbb2 426#endif // _WX_DYNLIB_H__