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"
25 // FIXME: can this go in private.h or something too??
26 #if defined(__WXPM__) || defined(__EMX__)
32 #include "wx/msw/private.h"
35 // ----------------------------------------------------------------------------
36 // conditional compilation
37 // ----------------------------------------------------------------------------
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)
45 typedef void *wxDllType
;
46 #elif defined(HAVE_SHL_LOAD)
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
;
55 #error "Dynamic Loading classes can't be compiled on this platform, sorry."
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
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
68 wxDL_VERBATIM
= 0x00000008, // Attempt to load the supplied library
69 // name without appending the usual dll
70 // filename extension.
72 wxDL_NOSHARE
= 0x00000010, // load new DLL, don't reuse already loaded
76 wxDL_DEFAULT
= wxDL_LAZY
78 wxDL_DEFAULT
= wxDL_LAZY
| wxDL_GLOBAL
82 enum wxDynamicLibraryCategory
84 wxDL_LIBRARY
, // standard library
85 wxDL_MODULE
// loadable module/plugin
90 wxDL_PLUGIN_GUI
, // plugin that uses GUI classes
91 wxDL_PLUGIN_BASE
// wxBase-only plugin
94 // ----------------------------------------------------------------------------
96 // ----------------------------------------------------------------------------
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
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))
109 // ---------------------------------------------------------------------------
111 // ---------------------------------------------------------------------------
113 class WXDLLIMPEXP_BASE wxDynamicLibrary
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();
120 // return the platform standard DLL extension (with leading dot)
121 static const wxChar
*GetDllExt() { return ms_dllext
; }
123 wxDynamicLibrary() : m_handle(0) { }
124 wxDynamicLibrary(const wxString
& libname
, int flags
= wxDL_DEFAULT
)
127 Load(libname
, flags
);
130 // NOTE: this class is (deliberately) not virtual, do not attempt
131 // to use it polymorphically.
132 ~wxDynamicLibrary() { Unload(); }
134 // return TRUE if the library was loaded successfully
135 bool IsLoaded() const { return m_handle
!= 0; }
137 // load the library with the given name (full or not), return true if ok
138 bool Load(wxString libname
, int flags
= wxDL_DEFAULT
);
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
143 wxDllType
Detach() { wxDllType h
= m_handle
; m_handle
= 0; return h
; }
145 // unload the given library handle (presumably returned by Detach() before)
146 static void Unload(wxDllType handle
);
148 // unload the library, also done automatically in dtor
149 void Unload() { if ( IsLoaded() ) { Unload(m_handle
); m_handle
= 0; } }
151 // Return the raw handle from dlopen and friends.
152 wxDllType
GetLibHandle() const { return m_handle
; }
154 // resolve a symbol in a loaded DLL, such as a variable or function name.
155 // 'name' is the (possibly mangled) name of the symbol. (use extern "C" to
156 // export unmangled names)
158 // Since it is perfectly valid for the returned symbol to actually be NULL,
159 // that is not always indication of an error. Pass and test the parameter
160 // 'success' for a true indication of success or failure to load the
163 // Returns a pointer to the symbol on success, or NULL if an error occurred
164 // or the symbol wasn't found.
165 void *GetSymbol(const wxString
& name
, bool *success
= 0) const;
168 // return platform-specific name of dynamic library with proper extension
169 // and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
170 static wxString
CanonicalizeName(const wxString
& name
,
171 wxDynamicLibraryCategory cat
= wxDL_LIBRARY
);
173 // return name of wxWidgets plugin (adds compiler and version info
176 CanonicalizePluginName(const wxString
& name
,
177 wxPluginCategory cat
= wxDL_PLUGIN_GUI
);
179 // return plugin directory on platforms where it makes sense and empty
181 static wxString
GetPluginsDirectory();
184 #if WXWIN_COMPATIBILITY_2_2
185 operator bool() const { return IsLoaded(); }
189 // platform specific shared lib suffix.
190 static const wxChar
*ms_dllext
;
192 // the handle to DLL or NULL
195 // no copy ctor/assignment operators (or we'd try to unload the library
197 DECLARE_NO_COPY_CLASS(wxDynamicLibrary
)
201 // ----------------------------------------------------------------------------
202 // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
203 // ----------------------------------------------------------------------------
205 #if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
208 wxDllLoader is a class providing an interface similar to unix's dlopen().
209 It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
210 DLLs and the resolving of symbols in them. There are no instances of this
211 class, it simply serves as a namespace for its static member functions.
213 class WXDLLIMPEXP_BASE wxDllLoader
217 This function loads the shared library libname into memory.
219 libname may be either the full path to the file or just the filename in
220 which case the library is searched for in all standard locations
221 (use GetDllExt() to construct the filename)
223 if success pointer is not NULL, it will be filled with TRUE if everything
224 went ok and FALSE otherwise
226 static wxDllType
LoadLibrary(const wxString
& name
, bool *success
= NULL
);
229 This function unloads the shared library previously loaded with
232 static void UnloadLibrary(wxDllType dll
);
235 This function returns a valid handle for the main program
236 itself or NULL if back linking is not supported by the current platform
239 static wxDllType
GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
242 This function resolves a symbol in a loaded DLL, such as a
243 variable or function name.
245 dllHandle Handle of the DLL, as returned by LoadDll().
246 name Name of the symbol.
248 Returns the pointer to the symbol or NULL on error.
250 static void *GetSymbol(wxDllType dllHandle
, const wxString
&name
, bool *success
= 0);
252 // return the standard DLL extension (with leading dot) for this platform
253 static wxString
GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
257 wxDllLoader(); // forbid construction of objects
261 // ----------------------------------------------------------------------------
263 // ----------------------------------------------------------------------------
267 class WXDLLIMPEXP_BASE wxLibrary
: public wxObject
270 wxLibrary(wxDllType handle
);
271 virtual ~wxLibrary();
273 // Get a symbol from the dynamic library
274 void *GetSymbol(const wxString
& symbname
);
276 // Create the object whose classname is "name"
277 wxObject
*CreateObject(const wxString
& name
);
280 void PrepareClasses(wxClassInfo
*first
);
285 wxHashTable classTable
;
288 // ----------------------------------------------------------------------------
290 // ----------------------------------------------------------------------------
292 class WXDLLIMPEXP_BASE wxLibraries
298 // caller is responsible for deleting the returned pointer if !NULL
299 wxLibrary
*LoadLibrary(const wxString
& basename
);
301 wxObject
*CreateObject(const wxString
& name
);
307 // ----------------------------------------------------------------------------
309 // ----------------------------------------------------------------------------
311 extern WXDLLIMPEXP_DATA_BASE(wxLibraries
) wxTheLibraries
;
313 #endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
315 // ----------------------------------------------------------------------------
316 // Interesting defines
317 // ----------------------------------------------------------------------------
319 #define WXDLL_ENTRY_FUNCTION() \
320 extern "C" WXEXPORT const wxClassInfo *wxGetClassFirst(); \
321 const wxClassInfo *wxGetClassFirst() { \
322 return wxClassInfo::GetFirst(); \
325 #endif // wxUSE_DYNLIB_CLASS
327 #endif // _WX_DYNLIB_H__