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