1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Dynamic library loading classes
4 // Author: Guilhem Lavaux, Vadim Zeitlin, Vaclav Slavik
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_DYNLIB_H__
13 #define _WX_DYNLIB_H__
17 #if wxUSE_DYNLIB_CLASS
19 #include "wx/string.h"
20 #include "wx/dynarray.h"
22 #if defined(__WXPM__) || defined(__EMX__)
23 #include "wx/os2/private.h"
27 #include "wx/msw/private.h"
30 #if defined(HAVE_DLERROR) && !defined(__EMX__)
31 #define wxHAVE_DYNLIB_ERROR
34 class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator
;
36 // ----------------------------------------------------------------------------
37 // conditional compilation
38 // ----------------------------------------------------------------------------
40 // Note: WXPM/EMX has to be tested first, since we want to use
41 // native version, even if configure detected presence of DLOPEN.
42 #if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
43 typedef HMODULE wxDllType
;
44 #elif defined(HAVE_DLOPEN)
46 typedef void *wxDllType
;
47 #elif defined(HAVE_SHL_LOAD)
49 typedef shl_t wxDllType
;
50 #elif defined(__DARWIN__)
51 typedef void *wxDllType
;
52 #elif defined(__WXMAC__)
53 #include <CodeFragments.h>
54 typedef CFragConnectionID wxDllType
;
56 #error "Dynamic Loading classes can't be compiled on this platform, sorry."
59 // ----------------------------------------------------------------------------
61 // ----------------------------------------------------------------------------
65 wxDL_LAZY
= 0x00000001, // resolve undefined symbols at first use
66 // (only works on some Unix versions)
67 wxDL_NOW
= 0x00000002, // resolve undefined symbols on load
68 // (default, always the case under Win32)
69 wxDL_GLOBAL
= 0x00000004, // export extern symbols to subsequently
71 wxDL_VERBATIM
= 0x00000008, // attempt to load the supplied library
72 // name without appending the usual dll
73 // filename extension.
74 wxDL_NOSHARE
= 0x00000010, // load new DLL, don't reuse already loaded
75 // (only for wxPluginManager)
77 wxDL_DEFAULT
= wxDL_NOW
// default flags correspond to Win32
80 enum wxDynamicLibraryCategory
82 wxDL_LIBRARY
, // standard library
83 wxDL_MODULE
// loadable module/plugin
88 wxDL_PLUGIN_GUI
, // plugin that uses GUI classes
89 wxDL_PLUGIN_BASE
// wxBase-only plugin
92 // ----------------------------------------------------------------------------
94 // ----------------------------------------------------------------------------
96 // when loading a function from a DLL you always have to cast the returned
97 // "void *" pointer to the correct type and, even more annoyingly, you have to
98 // repeat this type twice if you want to declare and define a function pointer
101 // this macro makes this slightly less painful by allowing you to specify the
102 // type only once, as the first parameter, and creating a variable of this type
103 // called "pfn<name>" initialized with the "name" from the "dynlib"
104 #define wxDYNLIB_FUNCTION(type, name, dynlib) \
105 type pfn ## name = (type)(dynlib).GetSymbol(_T(#name))
107 // ----------------------------------------------------------------------------
108 // wxDynamicLibraryDetails: contains details about a loaded wxDynamicLibrary
109 // ----------------------------------------------------------------------------
111 class WXDLLIMPEXP_BASE wxDynamicLibraryDetails
114 // ctor, normally never used as these objects are only created by
115 // wxDynamicLibrary::ListLoaded()
116 wxDynamicLibraryDetails() { m_address
= NULL
; m_length
= 0; }
118 // get the (base) name
119 wxString
GetName() const { return m_name
; }
121 // get the full path of this object
122 wxString
GetPath() const { return m_path
; }
124 // get the load address and the extent, return true if this information is
126 bool GetAddress(void **addr
, size_t *len
) const
139 // return the version of the DLL (may be empty if no version info)
140 wxString
GetVersion() const
153 friend class wxDynamicLibraryDetailsCreator
;
156 WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetails
,
157 wxDynamicLibraryDetailsArray
,
160 // ----------------------------------------------------------------------------
161 // wxDynamicLibrary: represents a handle to a DLL/shared object
162 // ----------------------------------------------------------------------------
164 class WXDLLIMPEXP_BASE wxDynamicLibrary
167 // return a valid handle for the main program itself or NULL if back
168 // linking is not supported by the current platform (e.g. Win32)
169 static wxDllType
GetProgramHandle();
171 // return the platform standard DLL extension (with leading dot)
172 static const wxChar
*GetDllExt() { return ms_dllext
; }
174 wxDynamicLibrary() : m_handle(0) { }
175 wxDynamicLibrary(const wxString
& libname
, int flags
= wxDL_DEFAULT
)
178 Load(libname
, flags
);
181 // NOTE: this class is (deliberately) not virtual, do not attempt
182 // to use it polymorphically.
183 ~wxDynamicLibrary() { Unload(); }
185 // return true if the library was loaded successfully
186 bool IsLoaded() const { return m_handle
!= 0; }
188 // load the library with the given name (full or not), return true if ok
189 bool Load(const wxString
& libname
, int flags
= wxDL_DEFAULT
);
191 // raw function for loading dynamic libs: always behaves as if
192 // wxDL_VERBATIM were specified and doesn't log error message if the
193 // library couldn't be loaded but simply returns NULL
194 static wxDllType
RawLoad(const wxString
& libname
, int flags
= wxDL_DEFAULT
);
196 // detach the library object from its handle, i.e. prevent the object from
197 // unloading the library in its dtor -- the caller is now responsible for
199 wxDllType
Detach() { wxDllType h
= m_handle
; m_handle
= 0; return h
; }
201 // unload the given library handle (presumably returned by Detach() before)
202 static void Unload(wxDllType handle
);
204 // unload the library, also done automatically in dtor
205 void Unload() { if ( IsLoaded() ) { Unload(m_handle
); m_handle
= 0; } }
207 // Return the raw handle from dlopen and friends.
208 wxDllType
GetLibHandle() const { return m_handle
; }
210 // check if the given symbol is present in the library, useful to verify if
211 // a loadable module is our plugin, for example, without provoking error
212 // messages from GetSymbol()
213 bool HasSymbol(const wxString
& name
) const
216 DoGetSymbol(name
, &ok
);
220 // resolve a symbol in a loaded DLL, such as a variable or function name.
221 // 'name' is the (possibly mangled) name of the symbol. (use extern "C" to
222 // export unmangled names)
224 // Since it is perfectly valid for the returned symbol to actually be NULL,
225 // that is not always indication of an error. Pass and test the parameter
226 // 'success' for a true indication of success or failure to load the
229 // Returns a pointer to the symbol on success, or NULL if an error occurred
230 // or the symbol wasn't found.
231 void *GetSymbol(const wxString
& name
, bool *success
= NULL
) const;
233 // low-level version of GetSymbol()
234 static void *RawGetSymbol(wxDllType handle
, const wxString
& name
);
235 void *RawGetSymbol(const wxString
& name
) const
237 #if defined (__WXPM__) || defined(__EMX__)
238 return GetSymbol(name
);
240 return RawGetSymbol(m_handle
, name
);
245 // this function is useful for loading functions from the standard Windows
246 // DLLs: such functions have an 'A' (in ANSI build) or 'W' (in Unicode, or
247 // wide character build) suffix if they take string parameters
248 static void *RawGetSymbolAorW(wxDllType handle
, const wxString
& name
)
262 void *GetSymbolAorW(const wxString
& name
) const
264 return RawGetSymbolAorW(m_handle
, name
);
268 // return all modules/shared libraries in the address space of this process
270 // returns an empty array if not implemented or an error occurred
271 static wxDynamicLibraryDetailsArray
ListLoaded();
273 // return platform-specific name of dynamic library with proper extension
274 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
275 static wxString
CanonicalizeName(const wxString
& name
,
276 wxDynamicLibraryCategory cat
= wxDL_LIBRARY
);
278 // return name of wxWidgets plugin (adds compiler and version info
281 CanonicalizePluginName(const wxString
& name
,
282 wxPluginCategory cat
= wxDL_PLUGIN_GUI
);
284 // return plugin directory on platforms where it makes sense and empty
286 static wxString
GetPluginsDirectory();
289 #if WXWIN_COMPATIBILITY_2_2
290 operator bool() const { return IsLoaded(); }
294 // common part of GetSymbol() and HasSymbol()
295 void *DoGetSymbol(const wxString
& name
, bool *success
= 0) const;
297 #ifdef wxHAVE_DYNLIB_ERROR
298 // log the error after a dlxxx() function failure
300 #endif // wxHAVE_DYNLIB_ERROR
303 // platform specific shared lib suffix.
304 static const wxChar
*ms_dllext
;
306 // the handle to DLL or NULL
309 // no copy ctor/assignment operators (or we'd try to unload the library
311 DECLARE_NO_COPY_CLASS(wxDynamicLibrary
)
315 // ----------------------------------------------------------------------------
316 // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
317 // ----------------------------------------------------------------------------
319 #if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
321 #include "wx/object.h"
324 wxDllLoader is a class providing an interface similar to unix's dlopen().
325 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
326 DLLs and the resolving of symbols in them. There are no instances of this
327 class, it simply serves as a namespace for its static member functions.
329 class WXDLLIMPEXP_BASE wxDllLoader
333 This function loads the shared library libname into memory.
335 libname may be either the full path to the file or just the filename in
336 which case the library is searched for in all standard locations
337 (use GetDllExt() to construct the filename)
339 if success pointer is not NULL, it will be filled with true if everything
340 went ok and false otherwise
342 static wxDllType
LoadLibrary(const wxString
& name
, bool *success
= NULL
);
345 This function unloads the shared library previously loaded with
348 static void UnloadLibrary(wxDllType dll
);
351 This function returns a valid handle for the main program
352 itself or NULL if back linking is not supported by the current platform
355 static wxDllType
GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
358 This function resolves a symbol in a loaded DLL, such as a
359 variable or function name.
361 dllHandle Handle of the DLL, as returned by LoadDll().
362 name Name of the symbol.
364 Returns the pointer to the symbol or NULL on error.
366 static void *GetSymbol(wxDllType dllHandle
, const wxString
&name
, bool *success
= 0);
368 // return the standard DLL extension (with leading dot) for this platform
369 static wxString
GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
373 wxDllLoader(); // forbid construction of objects
377 // ----------------------------------------------------------------------------
379 // ----------------------------------------------------------------------------
383 class WXDLLIMPEXP_BASE wxLibrary
: public wxObject
386 wxLibrary(wxDllType handle
);
387 virtual ~wxLibrary();
389 // Get a symbol from the dynamic library
390 void *GetSymbol(const wxString
& symbname
);
392 // Create the object whose classname is "name"
393 wxObject
*CreateObject(const wxString
& name
);
396 void PrepareClasses(wxClassInfo
*first
);
401 wxHashTable classTable
;
404 // ----------------------------------------------------------------------------
406 // ----------------------------------------------------------------------------
408 class WXDLLIMPEXP_BASE wxLibraries
414 // caller is responsible for deleting the returned pointer if !NULL
415 wxLibrary
*LoadLibrary(const wxString
& basename
);
417 wxObject
*CreateObject(const wxString
& name
);
423 // ----------------------------------------------------------------------------
425 // ----------------------------------------------------------------------------
427 extern WXDLLIMPEXP_DATA_BASE(wxLibraries
) wxTheLibraries
;
429 #endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
431 // ----------------------------------------------------------------------------
432 // Interesting defines
433 // ----------------------------------------------------------------------------
435 #define WXDLL_ENTRY_FUNCTION() \
436 extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
437 const wxClassInfo *wxGetClassFirst() { \
438 return wxClassInfo::GetFirst(); \
441 #endif // wxUSE_DYNLIB_CLASS
443 #endif // _WX_DYNLIB_H__