]> git.saurik.com Git - wxWidgets.git/blame - src/common/dynlib.cpp
don't crash when loading images with verbose==false (patch 1449823)
[wxWidgets.git] / src / common / dynlib.cpp
CommitLineData
7a4b9130 1/////////////////////////////////////////////////////////////////////////////
55034339 2// Name: src/common/dynlib.cpp
7a4b9130
GL
3// Purpose: Dynamic library management
4// Author: Guilhem Lavaux
5// Modified by:
6// Created: 20/07/98
7// RCS-ID: $Id$
da55d064
VZ
8// Copyright: (c) 1998 Guilhem Lavaux
9// 2000-2005 Vadim Zeitlin
65571936 10// Licence: wxWindows licence
7a4b9130
GL
11/////////////////////////////////////////////////////////////////////////////
12
da55d064
VZ
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
7b0bfbb2
VZ
16// ============================================================================
17// declarations
18// ============================================================================
19
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
23
0c32066b
JS
24#include "wx/wxprec.h"
25
2df7be7f
RR
26#ifdef __BORLANDC__
27 #pragma hdrstop
28#endif
f6bcfd97 29
1948bb32 30#if wxUSE_DYNLIB_CLASS
8a0d4cf6 31
7b0bfbb2
VZ
32#include "wx/dynlib.h"
33#include "wx/filefn.h"
34#include "wx/intl.h"
35#include "wx/log.h"
1948bb32
VS
36#include "wx/utils.h"
37#include "wx/filename.h" // for SplitPath()
a8eaaeb2
VS
38#include "wx/app.h"
39#include "wx/apptrait.h"
7b0bfbb2 40
defbed48
VZ
41#include "wx/arrimpl.cpp"
42
76a5e5d2
SC
43#if defined(__WXMAC__)
44 #include "wx/mac/private.h"
45#endif
46
4115960d 47WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray)
7b0bfbb2 48
1948bb32
VS
49// ============================================================================
50// implementation
51// ============================================================================
846e1424 52
a585ca5c 53// ---------------------------------------------------------------------------
1948bb32 54// wxDynamicLibrary
a585ca5c 55// ---------------------------------------------------------------------------
7b0bfbb2 56
defbed48 57#if defined(__WXPM__) || defined(__EMX__)
1948bb32 58 const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
87ec9b8f 59#elif defined(__WXMAC__) && !defined(__DARWIN__)
b494c48b 60 const wxChar *wxDynamicLibrary::ms_dllext = wxEmptyString;
f6bcfd97 61#endif
f6bcfd97 62
6d94009f 63// for MSW/Unix it is defined in platform-specific file
86a6ecff 64#if !(defined(__WXMSW__) || defined(__UNIX__)) || defined(__EMX__)
da55d064 65
1948bb32 66wxDllType wxDynamicLibrary::GetProgramHandle()
0868079c 67{
da55d064 68 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
7742efff 69 return 0;
0868079c
KB
70}
71
6d94009f
VZ
72#endif // __WXMSW__ || __UNIX__
73
da55d064 74
defbed48 75bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
a585ca5c 76{
1948bb32
VS
77 wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
78
79 // add the proper extension for the DLL ourselves unless told not to
defbed48 80 wxString libname = libnameOrig;
1948bb32
VS
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 }
7b0bfbb2 91
1948bb32
VS
92 // different ways to load a shared library
93 //
94 // FIXME: should go to the platform-specific files!
95#if defined(__WXMAC__) && !defined(__DARWIN__)
0b9ab0bd
RL
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,
1948bb32 107 &m_handle,
0b9ab0bd
RL
108 &myMainAddr,
109 myErrName ) != noErr )
7cc98b3e 110 {
0b9ab0bd
RL
111 wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
112 libname.c_str(),
fb44fc34 113 wxMacMakeStringFromPascal( myErrName ).c_str() );
1948bb32 114 m_handle = 0;
7cc98b3e 115 }
0b9ab0bd 116
1a787c5d 117#elif defined(__WXPM__) || defined(__EMX__)
1948bb32 118 char err[256] = "";
18ed8e00 119 DosLoadModule(err, sizeof(err), (PSZ)libname.c_str(), &m_handle);
6c286397 120#else // this should be the only remaining branch eventually
da55d064 121 m_handle = RawLoad(libname, flags);
1948bb32
VS
122#endif
123
124 if ( m_handle == 0 )
7cc98b3e 125 {
da55d064
VZ
126#ifdef wxHAVE_DYNLIB_ERROR
127 Error();
1948bb32 128#else
da55d064 129 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
0b9ab0bd 130#endif
7cc98b3e
VZ
131 }
132
1948bb32 133 return IsLoaded();
a585ca5c
KB
134}
135
da55d064
VZ
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!
e9737ede 139#if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__)
defbed48 140
9d033af9
VZ
141/* static */
142void wxDynamicLibrary::Unload(wxDllType handle)
752c7d6b 143{
55034339 144#if defined(__OS2__) || defined(__EMX__)
ff793cab 145 DosFreeModule( handle );
1948bb32 146#elif defined(__WXMAC__) && !defined(__DARWIN__)
ff793cab 147 CloseConnection( (CFragConnectionID*) &handle );
1948bb32 148#else
9d033af9 149 #error "runtime shared lib support not implemented"
1948bb32 150#endif
752c7d6b
KB
151}
152
da55d064 153#endif // !(__WXMSW__ || __UNIX__)
defbed48 154
a018a119 155void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
a585ca5c 156{
1948bb32
VS
157 wxCHECK_MSG( IsLoaded(), NULL,
158 _T("Can't load symbol from unloaded library") );
159
0b9ab0bd 160 void *symbol = 0;
a585ca5c 161
999836aa 162 wxUnusedVar(symbol);
1948bb32 163#if defined(__WXMAC__) && !defined(__DARWIN__)
0b9ab0bd
RL
164 Ptr symAddress;
165 CFragSymbolClass symClass;
166 Str255 symName;
1948bb32 167#if TARGET_CARBON
f73bc315 168 c2pstrcpy( (StringPtr) symName, name.fn_str() );
1948bb32 169#else
f73bc315 170 strcpy( (char *)symName, name.fn_str() );
1948bb32
VS
171 c2pstr( (char *)symName );
172#endif
609533d5 173 if( FindSymbol( m_handle, symName, &symAddress, &symClass ) == noErr )
0b9ab0bd 174 symbol = (void *)symAddress;
0b9ab0bd 175#elif defined(__WXPM__) || defined(__EMX__)
18ed8e00 176 DosQueryProcAddr( m_handle, 1L, (PSZ)name.c_str(), (PFN*)symbol );
1c193821 177#else
da55d064 178 symbol = RawGetSymbol(m_handle, name);
1c193821 179#endif
0b9ab0bd 180
a018a119
VZ
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);
7b0bfbb2
VZ
190 if ( !symbol )
191 {
da55d064
VZ
192#ifdef wxHAVE_DYNLIB_ERROR
193 Error();
0b9ab0bd 194#else
7cc98b3e
VZ
195 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
196 name.c_str());
0b9ab0bd 197#endif
7b0bfbb2 198 }
0b9ab0bd 199
7b0bfbb2 200 return symbol;
7a4b9130 201}
5fccb5b4 202
defbed48
VZ
203// ----------------------------------------------------------------------------
204// informational methods
205// ----------------------------------------------------------------------------
206
1948bb32 207/*static*/
350fffae
VZ
208wxString
209wxDynamicLibrary::CanonicalizeName(const wxString& name,
da55d064 210 wxDynamicLibraryCategory cat)
7a4b9130 211{
350fffae
VZ
212 wxString nameCanonic;
213
87ec9b8f 214 // under Unix the library names usually start with "lib" prefix, add it
e9737ede 215#if defined(__UNIX__) && !defined(__EMX__)
350fffae
VZ
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 }
da55d064
VZ
231#else // !__UNIX__
232 wxUnusedVar(cat);
233#endif // __UNIX__/!__UNIX__
350fffae
VZ
234
235 nameCanonic << name << GetDllExt();
236 return nameCanonic;
7a4b9130 237}
8a0d4cf6 238
1948bb32
VS
239/*static*/
240wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
241 wxPluginCategory cat)
f11bdd03 242{
1948bb32
VS
243 wxString suffix;
244 if ( cat == wxDL_PLUGIN_GUI )
f11bdd03 245 {
a8eaaeb2
VS
246 wxAppTraits *traits = wxAppConsole::GetInstance() ?
247 wxAppConsole::GetInstance()->GetTraits() : NULL;
306608eb
VZ
248 wxCHECK_MSG( traits, _T(""),
249 _("can't query for GUI plugins name in console applications") );
324899f6 250 suffix = traits->GetToolkitInfo().shortName;
f11bdd03 251 }
1948bb32
VS
252#if wxUSE_UNICODE
253 suffix << _T('u');
254#endif
255#ifdef __WXDEBUG__
256 suffix << _T('d');
257#endif
f11bdd03 258
1948bb32
VS
259 if ( !suffix.empty() )
260 suffix = wxString(_T("_")) + suffix;
f11bdd03 261
3546ffae 262#define WXSTRINGIZE(x) #x
e9737ede 263#if defined(__UNIX__) && !defined(__EMX__)
1948bb32 264 #if (wxMINOR_VERSION % 2) == 0
3546ffae 265 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y)
1948bb32 266 #else
3546ffae 267 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
1948bb32
VS
268 #endif
269#else
270 #if (wxMINOR_VERSION % 2) == 0
3546ffae 271 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
1948bb32 272 #else
3546ffae 273 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
1948bb32
VS
274 #endif
275#endif
350fffae 276
1948bb32
VS
277 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
278 wxRELEASE_NUMBER));
279#undef wxDLLVER
3546ffae 280#undef WXSTRINGIZE
f11bdd03 281
2c02ec05
VS
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
1948bb32 295 return CanonicalizeName(name + suffix, wxDL_MODULE);
f11bdd03 296}
5fccb5b4 297
1948bb32
VS
298/*static*/
299wxString wxDynamicLibrary::GetPluginsDirectory()
f11bdd03 300{
1948bb32
VS
301#ifdef __UNIX__
302 wxString format = wxGetInstallPrefix();
cb979fac 303 wxString dir;
1948bb32
VS
304 format << wxFILE_SEP_PATH
305 << wxT("lib") << wxFILE_SEP_PATH
306 << wxT("wx") << wxFILE_SEP_PATH
cb979fac 307#if (wxMINOR_VERSION % 2) == 0
1948bb32 308 << wxT("%i.%i");
1948bb32 309 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
1948bb32 310#else
cb979fac
VS
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__
1948bb32
VS
318 return wxEmptyString;
319#endif
f11bdd03
GD
320}
321
f11bdd03 322
1948bb32 323#endif // wxUSE_DYNLIB_CLASS