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