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