]> git.saurik.com Git - wxWidgets.git/blob - src/common/dynlib.cpp
use common bottleneck
[wxWidgets.git] / src / common / dynlib.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dynlib.cpp
3 // Purpose: Dynamic library management
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 20/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // 2000-2005 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 //FIXME: This class isn't really common at all, it should be moved into
14 // platform dependent files (already done for Windows and Unix)
15
16 // ============================================================================
17 // declarations
18 // ============================================================================
19
20 // ----------------------------------------------------------------------------
21 // headers
22 // ----------------------------------------------------------------------------
23
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #if wxUSE_DYNLIB_CLASS
31
32 #include "wx/dynlib.h"
33
34 #ifndef WX_PRECOMP
35 #include "wx/intl.h"
36 #include "wx/log.h"
37 #include "wx/app.h"
38 #include "wx/utils.h"
39 #endif //WX_PRECOMP
40
41 #include "wx/filefn.h"
42 #include "wx/filename.h" // for SplitPath()
43 #include "wx/platinfo.h"
44
45 #include "wx/arrimpl.cpp"
46
47 WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray)
48
49 // ============================================================================
50 // implementation
51 // ============================================================================
52
53 // ---------------------------------------------------------------------------
54 // wxDynamicLibrary
55 // ---------------------------------------------------------------------------
56
57 // for MSW/Unix it is defined in platform-specific file
58 #if !(defined(__WINDOWS__) || defined(__UNIX__)) || defined(__EMX__)
59
60 wxDllType wxDynamicLibrary::GetProgramHandle()
61 {
62 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
63 return 0;
64 }
65
66 #endif // __WINDOWS__ || __UNIX__
67
68
69 bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
70 {
71 wxASSERT_MSG(m_handle == 0, wxT("Library already loaded."));
72
73 // add the proper extension for the DLL ourselves unless told not to
74 wxString libname = libnameOrig;
75 if ( !(flags & wxDL_VERBATIM) )
76 {
77 // and also check that the libname doesn't already have it
78 wxString ext;
79 wxFileName::SplitPath(libname, NULL, NULL, &ext);
80 if ( ext.empty() )
81 {
82 libname += GetDllExt(wxDL_MODULE);
83 }
84 }
85
86 // different ways to load a shared library
87 //
88 // FIXME: should go to the platform-specific files!
89 #if defined(__WXPM__) || defined(__EMX__)
90 char err[256] = "";
91 DosLoadModule(err, sizeof(err), libname.c_str(), &m_handle);
92 #else // this should be the only remaining branch eventually
93 m_handle = RawLoad(libname, flags);
94 #endif
95
96 if ( m_handle == 0 && !(flags & wxDL_QUIET) )
97 {
98 #ifdef wxHAVE_DYNLIB_ERROR
99 Error();
100 #else
101 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
102 #endif
103 }
104
105 return IsLoaded();
106 }
107
108 // for MSW and Unix this is implemented in the platform-specific file
109 //
110 // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp!
111 #if (!defined(__WINDOWS__) && !defined(__UNIX__)) || defined(__EMX__)
112
113 /* static */
114 void wxDynamicLibrary::Unload(wxDllType handle)
115 {
116 #if defined(__OS2__) || defined(__EMX__)
117 DosFreeModule( handle );
118 #else
119 #error "runtime shared lib support not implemented"
120 #endif
121 }
122
123 #endif // !(__WINDOWS__ || __UNIX__)
124
125 void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
126 {
127 wxCHECK_MSG( IsLoaded(), NULL,
128 wxT("Can't load symbol from unloaded library") );
129
130 void *symbol = 0;
131
132 wxUnusedVar(symbol);
133 #if defined(__WXPM__) || defined(__EMX__)
134 DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol );
135 #else
136 symbol = RawGetSymbol(m_handle, name);
137 #endif
138
139 if ( success )
140 *success = symbol != NULL;
141
142 return symbol;
143 }
144
145 void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
146 {
147 void *symbol = DoGetSymbol(name, success);
148 if ( !symbol )
149 {
150 #ifdef wxHAVE_DYNLIB_ERROR
151 Error();
152 #else
153 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
154 name.c_str());
155 #endif
156 }
157
158 return symbol;
159 }
160
161 // ----------------------------------------------------------------------------
162 // informational methods
163 // ----------------------------------------------------------------------------
164
165 /*static*/
166 wxString wxDynamicLibrary::GetDllExt(wxDynamicLibraryCategory cat)
167 {
168 wxUnusedVar(cat);
169 #if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
170 return ".dll";
171 #elif defined(__HPUX__)
172 return ".sl";
173 #elif defined(__DARWIN__)
174 switch ( cat )
175 {
176 case wxDL_LIBRARY:
177 return ".dylib";
178 case wxDL_MODULE:
179 return ".bundle";
180 }
181 wxFAIL_MSG("unreachable");
182 return wxString(); // silence gcc warning
183 #else
184 return ".so";
185 #endif
186 }
187
188 /*static*/
189 wxString
190 wxDynamicLibrary::CanonicalizeName(const wxString& name,
191 wxDynamicLibraryCategory cat)
192 {
193 wxString nameCanonic;
194
195 // under Unix the library names usually start with "lib" prefix, add it
196 #if defined(__UNIX__) && !defined(__EMX__)
197 switch ( cat )
198 {
199 case wxDL_LIBRARY:
200 // Library names should start with "lib" under Unix.
201 nameCanonic = "lib";
202 break;
203 case wxDL_MODULE:
204 // Module names are arbitrary and should have no prefix added.
205 break;
206 }
207 #endif
208
209 nameCanonic << name << GetDllExt(cat);
210
211 return nameCanonic;
212 }
213
214 /*static*/
215 wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
216 wxPluginCategory cat)
217 {
218 wxString suffix;
219 if ( cat == wxDL_PLUGIN_GUI )
220 {
221 suffix = wxPlatformInfo::Get().GetPortIdShortName();
222 }
223 #if wxUSE_UNICODE
224 suffix << wxT('u');
225 #endif
226 #ifdef __WXDEBUG__
227 suffix << wxT('d');
228 #endif
229
230 if ( !suffix.empty() )
231 suffix = wxString(wxT("_")) + suffix;
232
233 #define WXSTRINGIZE(x) #x
234 #if defined(__UNIX__) && !defined(__EMX__)
235 #if (wxMINOR_VERSION % 2) == 0
236 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y)
237 #else
238 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
239 #endif
240 #else
241 #if (wxMINOR_VERSION % 2) == 0
242 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
243 #else
244 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
245 #endif
246 #endif
247
248 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
249 wxRELEASE_NUMBER));
250 #undef wxDLLVER
251 #undef WXSTRINGIZE
252
253 #ifdef __WINDOWS__
254 // Add compiler identification:
255 #if defined(__GNUG__)
256 suffix << wxT("_gcc");
257 #elif defined(__VISUALC__)
258 suffix << wxT("_vc");
259 #elif defined(__WATCOMC__)
260 suffix << wxT("_wat");
261 #elif defined(__BORLANDC__)
262 suffix << wxT("_bcc");
263 #endif
264 #endif
265
266 return CanonicalizeName(name + suffix, wxDL_MODULE);
267 }
268
269 /*static*/
270 wxString wxDynamicLibrary::GetPluginsDirectory()
271 {
272 #ifdef __UNIX__
273 wxString format = wxGetInstallPrefix();
274 wxString dir;
275 format << wxFILE_SEP_PATH
276 << wxT("lib") << wxFILE_SEP_PATH
277 << wxT("wx") << wxFILE_SEP_PATH
278 #if (wxMINOR_VERSION % 2) == 0
279 << wxT("%i.%i");
280 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
281 #else
282 << wxT("%i.%i.%i");
283 dir.Printf(format.c_str(),
284 wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER);
285 #endif
286 return dir;
287
288 #else // ! __UNIX__
289 return wxEmptyString;
290 #endif
291 }
292
293
294 #endif // wxUSE_DYNLIB_CLASS