]> git.saurik.com Git - wxWidgets.git/blob - src/common/dynlib.cpp
fixed hash collisions in ZIP files (patch 1082026)
[wxWidgets.git] / src / common / dynlib.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
25 # pragma implementation "dynlib.h"
26 #endif
27
28 #include "wx/wxprec.h"
29
30 #ifdef __BORLANDC__
31 #pragma hdrstop
32 #endif
33
34 #if wxUSE_DYNLIB_CLASS
35
36 #include "wx/dynlib.h"
37 #include "wx/filefn.h"
38 #include "wx/intl.h"
39 #include "wx/log.h"
40 #include "wx/utils.h"
41 #include "wx/filename.h" // for SplitPath()
42 #include "wx/app.h"
43 #include "wx/apptrait.h"
44
45 #include "wx/arrimpl.cpp"
46
47 #if defined(__WXMAC__)
48 #include "wx/mac/private.h"
49 #endif
50
51 WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray);
52
53 // ============================================================================
54 // implementation
55 // ============================================================================
56
57 // ---------------------------------------------------------------------------
58 // wxDynamicLibrary
59 // ---------------------------------------------------------------------------
60
61 #if defined(__WXPM__) || defined(__EMX__)
62 const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
63 #elif defined(__WXMAC__) && !defined(__DARWIN__)
64 const wxChar *wxDynamicLibrary::ms_dllext = wxEmptyString;
65 #endif
66
67 // for Unix it is in src/unix/dlunix.cpp
68 #if !defined(__UNIX__) || defined(__EMX__)
69
70 wxDllType wxDynamicLibrary::GetProgramHandle()
71 {
72 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
73 return 0;
74 }
75
76 #endif // __UNIX__
77
78 bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
79 {
80 wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
81
82 // add the proper extension for the DLL ourselves unless told not to
83 wxString libname = libnameOrig;
84 if ( !(flags & wxDL_VERBATIM) )
85 {
86 // and also check that the libname doesn't already have it
87 wxString ext;
88 wxFileName::SplitPath(libname, NULL, NULL, &ext);
89 if ( ext.empty() )
90 {
91 libname += GetDllExt();
92 }
93 }
94
95 // different ways to load a shared library
96 //
97 // FIXME: should go to the platform-specific files!
98 #if defined(__WXMAC__) && !defined(__DARWIN__)
99 FSSpec myFSSpec;
100 Ptr myMainAddr;
101 Str255 myErrName;
102
103 wxMacFilename2FSSpec( libname , &myFSSpec );
104
105 if( GetDiskFragment( &myFSSpec,
106 0,
107 kCFragGoesToEOF,
108 "\p",
109 kPrivateCFragCopy,
110 &m_handle,
111 &myMainAddr,
112 myErrName ) != noErr )
113 {
114 wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
115 libname.c_str(),
116 wxMacMakeStringFromPascal( myErrName ).c_str() );
117 m_handle = 0;
118 }
119
120 #elif defined(__WXPM__) || defined(__EMX__)
121 char err[256] = "";
122 DosLoadModule(err, sizeof(err), libname.c_str(), &m_handle);
123 #else
124 m_handle = RawLoad(libname, flags);
125 #endif
126
127 if ( m_handle == 0 )
128 {
129 #ifdef wxHAVE_DYNLIB_ERROR
130 Error();
131 #else
132 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
133 #endif
134 }
135
136 return IsLoaded();
137 }
138
139 // for MSW and Unix this is implemented in the platform-specific file
140 //
141 // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp!
142 #if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__)
143
144 /* static */
145 void wxDynamicLibrary::Unload(wxDllType handle)
146 {
147 #if defined(__WXPM__) || defined(__EMX__)
148 DosFreeModule( handle );
149 #elif defined(__WXMAC__) && !defined(__DARWIN__)
150 CloseConnection( (CFragConnectionID*) &handle );
151 #else
152 #error "runtime shared lib support not implemented"
153 #endif
154 }
155
156 #endif // !(__WXMSW__ || __UNIX__)
157
158 void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
159 {
160 wxCHECK_MSG( IsLoaded(), NULL,
161 _T("Can't load symbol from unloaded library") );
162
163 void *symbol = 0;
164
165 wxUnusedVar(symbol);
166 #if defined(__WXMAC__) && !defined(__DARWIN__)
167 Ptr symAddress;
168 CFragSymbolClass symClass;
169 Str255 symName;
170 #if TARGET_CARBON
171 c2pstrcpy( (StringPtr) symName, name.fn_str() );
172 #else
173 strcpy( (char *)symName, name.fn_str() );
174 c2pstr( (char *)symName );
175 #endif
176 if( FindSymbol( m_handle, symName, &symAddress, &symClass ) == noErr )
177 symbol = (void *)symAddress;
178 #elif defined(__WXPM__) || defined(__EMX__)
179 DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol );
180 #else
181 symbol = RawGetSymbol(m_handle, name);
182 #endif
183
184 if ( success )
185 *success = symbol != NULL;
186
187 return symbol;
188 }
189
190 void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
191 {
192 void *symbol = DoGetSymbol(name, success);
193 if ( !symbol )
194 {
195 #ifdef wxHAVE_DYNLIB_ERROR
196 Error();
197 #else
198 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
199 name.c_str());
200 #endif
201 }
202
203 return symbol;
204 }
205
206 // ----------------------------------------------------------------------------
207 // informational methods
208 // ----------------------------------------------------------------------------
209
210 /*static*/
211 wxString
212 wxDynamicLibrary::CanonicalizeName(const wxString& name,
213 wxDynamicLibraryCategory cat)
214 {
215 wxString nameCanonic;
216
217 // under Unix the library names usually start with "lib" prefix, add it
218 #if defined(__UNIX__) && !defined(__EMX__)
219 switch ( cat )
220 {
221 default:
222 wxFAIL_MSG( _T("unknown wxDynamicLibraryCategory value") );
223 // fall through
224
225 case wxDL_MODULE:
226 // don't do anything for modules, their names are arbitrary
227 break;
228
229 case wxDL_LIBRARY:
230 // library names should start with "lib" under Unix
231 nameCanonic = _T("lib");
232 break;
233 }
234 #else // !__UNIX__
235 wxUnusedVar(cat);
236 #endif // __UNIX__/!__UNIX__
237
238 nameCanonic << name << GetDllExt();
239 return nameCanonic;
240 }
241
242 /*static*/
243 wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
244 wxPluginCategory cat)
245 {
246 wxString suffix;
247 if ( cat == wxDL_PLUGIN_GUI )
248 {
249 wxAppTraits *traits = wxAppConsole::GetInstance() ?
250 wxAppConsole::GetInstance()->GetTraits() : NULL;
251 wxASSERT_MSG( traits,
252 _("can't query for GUI plugins name in console applications") );
253 suffix = traits->GetToolkitInfo().shortName;
254 }
255 #if wxUSE_UNICODE
256 suffix << _T('u');
257 #endif
258 #ifdef __WXDEBUG__
259 suffix << _T('d');
260 #endif
261
262 if ( !suffix.empty() )
263 suffix = wxString(_T("_")) + suffix;
264
265 #define WXSTRINGIZE(x) #x
266 #if defined(__UNIX__) && !defined(__EMX__)
267 #if (wxMINOR_VERSION % 2) == 0
268 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y)
269 #else
270 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
271 #endif
272 #else
273 #if (wxMINOR_VERSION % 2) == 0
274 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
275 #else
276 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
277 #endif
278 #endif
279
280 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
281 wxRELEASE_NUMBER));
282 #undef wxDLLVER
283 #undef WXSTRINGIZE
284
285 #ifdef __WINDOWS__
286 // Add compiler identification:
287 #if defined(__GNUG__)
288 suffix << _T("_gcc");
289 #elif defined(__VISUALC__)
290 suffix << _T("_vc");
291 #elif defined(__WATCOMC__)
292 suffix << _T("_wat");
293 #elif defined(__BORLANDC__)
294 suffix << _T("_bcc");
295 #endif
296 #endif
297
298 return CanonicalizeName(name + suffix, wxDL_MODULE);
299 }
300
301 /*static*/
302 wxString wxDynamicLibrary::GetPluginsDirectory()
303 {
304 #ifdef __UNIX__
305 wxString format = wxGetInstallPrefix();
306 wxString dir;
307 format << wxFILE_SEP_PATH
308 << wxT("lib") << wxFILE_SEP_PATH
309 << wxT("wx") << wxFILE_SEP_PATH
310 #if (wxMINOR_VERSION % 2) == 0
311 << wxT("%i.%i");
312 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
313 #else
314 << wxT("%i.%i.%i");
315 dir.Printf(format.c_str(),
316 wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER);
317 #endif
318 return dir;
319
320 #else // ! __UNIX__
321 return wxEmptyString;
322 #endif
323 }
324
325
326 #endif // wxUSE_DYNLIB_CLASS