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__
15 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
16 # pragma interface "dynlib.h"
21 #if wxUSE_DYNLIB_CLASS
23 #include "wx/string.h"
24 #include "wx/dynarray.h"
26 #if defined(__WXPM__) || defined(__EMX__)
27 #include "wx/os2/private.h"
31 #include "wx/msw/private.h"
34 #if defined(HAVE_DLERROR) && !defined(__EMX__)
35 #define wxHAVE_DYNLIB_ERROR
38 class WXDLLIMPEXP_BASE wxDynamicLibraryDetailsCreator
;
40 // ----------------------------------------------------------------------------
41 // conditional compilation
42 // ----------------------------------------------------------------------------
44 // Note: WXPM/EMX has to be tested first, since we want to use
45 // native version, even if configure detected presence of DLOPEN.
46 #if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
47 typedef HMODULE wxDllType
;
48 #elif defined(HAVE_DLOPEN)
50 typedef void *wxDllType
;
51 #elif defined(HAVE_SHL_LOAD)
53 typedef shl_t wxDllType
;
54 #elif defined(__DARWIN__)
55 typedef void *wxDllType
;
56 #elif defined(__WXMAC__)
57 #include <CodeFragments.h>
58 typedef CFragConnectionID wxDllType
;
60 #error "Dynamic Loading classes can't be compiled on this platform, sorry."
63 // ----------------------------------------------------------------------------
65 // ----------------------------------------------------------------------------
69 wxDL_LAZY
= 0x00000001, // resolve undefined symbols at first use
70 // (only works on some Unix versions)
71 wxDL_NOW
= 0x00000002, // resolve undefined symbols on load
72 // (default, always the case under Win32)
73 wxDL_GLOBAL
= 0x00000004, // export extern symbols to subsequently
75 wxDL_VERBATIM
= 0x00000008, // attempt to load the supplied library
76 // name without appending the usual dll
77 // filename extension.
78 wxDL_NOSHARE
= 0x00000010, // load new DLL, don't reuse already loaded
79 // (only for wxPluginManager)
81 wxDL_DEFAULT
= wxDL_NOW
// default flags correspond to Win32
84 enum wxDynamicLibraryCategory
86 wxDL_LIBRARY
, // standard library
87 wxDL_MODULE
// loadable module/plugin
92 wxDL_PLUGIN_GUI
, // plugin that uses GUI classes
93 wxDL_PLUGIN_BASE
// wxBase-only plugin
96 // ----------------------------------------------------------------------------
98 // ----------------------------------------------------------------------------
100 // when loading a function from a DLL you always have to cast the returned
101 // "void *" pointer to the correct type and, even more annoyingly, you have to
102 // repeat this type twice if you want to declare and define a function pointer
105 // this macro makes this slightly less painful by allowing you to specify the
106 // type only once, as the first parameter, and creating a variable of this type
107 // called "pfn<name>" initialized with the "name" from the "dynlib"
108 #define wxDYNLIB_FUNCTION(type, name, dynlib) \
109 type pfn ## name = (type)(dynlib).GetSymbol(_T(#name))
111 // ----------------------------------------------------------------------------
112 // wxDynamicLibraryDetails: contains details about a loaded wxDynamicLibrary
113 // ----------------------------------------------------------------------------
115 class WXDLLIMPEXP_BASE wxDynamicLibraryDetails
118 // ctor, normally never used as these objects are only created by
119 // wxDynamicLibrary::ListLoaded()
120 wxDynamicLibraryDetails() { m_address
= NULL
; m_length
= 0; }
122 // get the (base) name
123 wxString
GetName() const { return m_name
; }
125 // get the full path of this object
126 wxString
GetPath() const { return m_path
; }
128 // get the load address and the extent, return true if this information is
130 bool GetAddress(void **addr
, size_t *len
) const
143 // return the version of the DLL (may be empty if no version info)
144 wxString
GetVersion() const
157 friend class wxDynamicLibraryDetailsCreator
;
160 WX_DECLARE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetails
,
161 wxDynamicLibraryDetailsArray
,
164 // ----------------------------------------------------------------------------
165 // wxDynamicLibrary: represents a handle to a DLL/shared object
166 // ----------------------------------------------------------------------------
168 class WXDLLIMPEXP_BASE wxDynamicLibrary
171 // return a valid handle for the main program itself or NULL if back
172 // linking is not supported by the current platform (e.g. Win32)
173 static wxDllType
GetProgramHandle();
175 // return the platform standard DLL extension (with leading dot)
176 static const wxChar
*GetDllExt() { return ms_dllext
; }
178 wxDynamicLibrary() : m_handle(0) { }
179 wxDynamicLibrary(const wxString
& libname
, int flags
= wxDL_DEFAULT
)
182 Load(libname
, flags
);
185 // NOTE: this class is (deliberately) not virtual, do not attempt
186 // to use it polymorphically.
187 ~wxDynamicLibrary() { Unload(); }
189 // return true if the library was loaded successfully
190 bool IsLoaded() const { return m_handle
!= 0; }
192 // load the library with the given name (full or not), return true if ok
193 bool Load(const wxString
& libname
, int flags
= wxDL_DEFAULT
);
195 // raw function for loading dynamic libs: always behaves as if
196 // wxDL_VERBATIM were specified and doesn't log error message if the
197 // library couldn't be loaded but simply returns NULL
198 static wxDllType
RawLoad(const wxString
& libname
, int flags
= wxDL_DEFAULT
);
200 // detach the library object from its handle, i.e. prevent the object from
201 // unloading the library in its dtor -- the caller is now responsible for
203 wxDllType
Detach() { wxDllType h
= m_handle
; m_handle
= 0; return h
; }
205 // unload the given library handle (presumably returned by Detach() before)
206 static void Unload(wxDllType handle
);
208 // unload the library, also done automatically in dtor
209 void Unload() { if ( IsLoaded() ) { Unload(m_handle
); m_handle
= 0; } }
211 // Return the raw handle from dlopen and friends.
212 wxDllType
GetLibHandle() const { return m_handle
; }
214 // check if the given symbol is present in the library, useful to verify if
215 // a loadable module is our plugin, for example, without provoking error
216 // messages from GetSymbol()
217 bool HasSymbol(const wxString
& name
) const
220 DoGetSymbol(name
, &ok
);
224 // resolve a symbol in a loaded DLL, such as a variable or function name.
225 // 'name' is the (possibly mangled) name of the symbol. (use extern "C" to
226 // export unmangled names)
228 // Since it is perfectly valid for the returned symbol to actually be NULL,
229 // that is not always indication of an error. Pass and test the parameter
230 // 'success' for a true indication of success or failure to load the
233 // Returns a pointer to the symbol on success, or NULL if an error occurred
234 // or the symbol wasn't found.
235 void *GetSymbol(const wxString
& name
, bool *success
= NULL
) const;
237 // low-level version of GetSymbol()
238 static void *RawGetSymbol(wxDllType handle
, const wxString
& name
);
239 void *RawGetSymbol(const wxString
& name
) const
241 #if defined (__WXPM__) || defined(__EMX__)
242 return GetSymbol(name
);
244 return RawGetSymbol(m_handle
, name
);
249 // this function is useful for loading functions from the standard Windows
250 // DLLs: such functions have an 'A' (in ANSI build) or 'W' (in Unicode, or
251 // wide character build) suffix if they take string parameters
252 static void *RawGetSymbolAorW(wxDllType handle
, const wxString
& name
)
266 void *GetSymbolAorW(const wxString
& name
) const
268 return RawGetSymbolAorW(m_handle
, name
);
272 // return all modules/shared libraries in the address space of this process
274 // returns an empty array if not implemented or an error occurred
275 static wxDynamicLibraryDetailsArray
ListLoaded();
277 // return platform-specific name of dynamic library with proper extension
278 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
279 static wxString
CanonicalizeName(const wxString
& name
,
280 wxDynamicLibraryCategory cat
= wxDL_LIBRARY
);
282 // return name of wxWidgets plugin (adds compiler and version info
285 CanonicalizePluginName(const wxString
& name
,
286 wxPluginCategory cat
= wxDL_PLUGIN_GUI
);
288 // return plugin directory on platforms where it makes sense and empty
290 static wxString
GetPluginsDirectory();
293 #if WXWIN_COMPATIBILITY_2_2
294 operator bool() const { return IsLoaded(); }
298 // common part of GetSymbol() and HasSymbol()
299 void *DoGetSymbol(const wxString
& name
, bool *success
= 0) const;
301 #ifdef wxHAVE_DYNLIB_ERROR
302 // log the error after a dlxxx() function failure
304 #endif // wxHAVE_DYNLIB_ERROR
307 // platform specific shared lib suffix.
308 static const wxChar
*ms_dllext
;
310 // the handle to DLL or NULL
313 // no copy ctor/assignment operators (or we'd try to unload the library
315 DECLARE_NO_COPY_CLASS(wxDynamicLibrary
)
319 // ----------------------------------------------------------------------------
320 // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
321 // ----------------------------------------------------------------------------
323 #if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
325 #include "wx/object.h"
328 wxDllLoader is a class providing an interface similar to unix's dlopen().
329 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
330 DLLs and the resolving of symbols in them. There are no instances of this
331 class, it simply serves as a namespace for its static member functions.
333 class WXDLLIMPEXP_BASE wxDllLoader
337 This function loads the shared library libname into memory.
339 libname may be either the full path to the file or just the filename in
340 which case the library is searched for in all standard locations
341 (use GetDllExt() to construct the filename)
343 if success pointer is not NULL, it will be filled with true if everything
344 went ok and false otherwise
346 static wxDllType
LoadLibrary(const wxString
& name
, bool *success
= NULL
);
349 This function unloads the shared library previously loaded with
352 static void UnloadLibrary(wxDllType dll
);
355 This function returns a valid handle for the main program
356 itself or NULL if back linking is not supported by the current platform
359 static wxDllType
GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
362 This function resolves a symbol in a loaded DLL, such as a
363 variable or function name.
365 dllHandle Handle of the DLL, as returned by LoadDll().
366 name Name of the symbol.
368 Returns the pointer to the symbol or NULL on error.
370 static void *GetSymbol(wxDllType dllHandle
, const wxString
&name
, bool *success
= 0);
372 // return the standard DLL extension (with leading dot) for this platform
373 static wxString
GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
377 wxDllLoader(); // forbid construction of objects
381 // ----------------------------------------------------------------------------
383 // ----------------------------------------------------------------------------
387 class WXDLLIMPEXP_BASE wxLibrary
: public wxObject
390 wxLibrary(wxDllType handle
);
391 virtual ~wxLibrary();
393 // Get a symbol from the dynamic library
394 void *GetSymbol(const wxString
& symbname
);
396 // Create the object whose classname is "name"
397 wxObject
*CreateObject(const wxString
& name
);
400 void PrepareClasses(wxClassInfo
*first
);
405 wxHashTable classTable
;
408 // ----------------------------------------------------------------------------
410 // ----------------------------------------------------------------------------
412 class WXDLLIMPEXP_BASE wxLibraries
418 // caller is responsible for deleting the returned pointer if !NULL
419 wxLibrary
*LoadLibrary(const wxString
& basename
);
421 wxObject
*CreateObject(const wxString
& name
);
427 // ----------------------------------------------------------------------------
429 // ----------------------------------------------------------------------------
431 extern WXDLLIMPEXP_DATA_BASE(wxLibraries
) wxTheLibraries
;
433 #endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
435 // ----------------------------------------------------------------------------
436 // Interesting defines
437 // ----------------------------------------------------------------------------
439 #define WXDLL_ENTRY_FUNCTION() \
440 extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
441 const wxClassInfo *wxGetClassFirst() { \
442 return wxClassInfo::GetFirst(); \
445 #endif // wxUSE_DYNLIB_CLASS
447 #endif // _WX_DYNLIB_H__