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