]> git.saurik.com Git - wxWidgets.git/blob - src/common/dynlib.cpp
added Open() mode parameter
[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 MSW/Unix it is defined in platform-specific file
68 #if !(defined(__WXMSW__) || 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 // __WXMSW__ || __UNIX__
77
78
79 bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
80 {
81 wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
82
83 // add the proper extension for the DLL ourselves unless told not to
84 wxString libname = libnameOrig;
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 }
95
96 // different ways to load a shared library
97 //
98 // FIXME: should go to the platform-specific files!
99 #if defined(__WXMAC__) && !defined(__DARWIN__)
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,
111 &m_handle,
112 &myMainAddr,
113 myErrName ) != noErr )
114 {
115 wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
116 libname.c_str(),
117 wxMacMakeStringFromPascal( myErrName ).c_str() );
118 m_handle = 0;
119 }
120
121 #elif defined(__WXPM__) || defined(__EMX__)
122 char err[256] = "";
123 DosLoadModule(err, sizeof(err), (PSZ)libname.c_str(), &m_handle);
124 #else
125 m_handle = RawLoad(libname, flags);
126 #endif
127
128 if ( m_handle == 0 )
129 {
130 #ifdef wxHAVE_DYNLIB_ERROR
131 Error();
132 #else
133 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
134 #endif
135 }
136
137 return IsLoaded();
138 }
139
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!
143 #if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__)
144
145 /* static */
146 void wxDynamicLibrary::Unload(wxDllType handle)
147 {
148 #if defined(__WXPM__) || defined(__EMX__)
149 DosFreeModule( handle );
150 #elif defined(__WXMAC__) && !defined(__DARWIN__)
151 CloseConnection( (CFragConnectionID*) &handle );
152 #else
153 #error "runtime shared lib support not implemented"
154 #endif
155 }
156
157 #endif // !(__WXMSW__ || __UNIX__)
158
159 void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
160 {
161 wxCHECK_MSG( IsLoaded(), NULL,
162 _T("Can't load symbol from unloaded library") );
163
164 void *symbol = 0;
165
166 wxUnusedVar(symbol);
167 #if defined(__WXMAC__) && !defined(__DARWIN__)
168 Ptr symAddress;
169 CFragSymbolClass symClass;
170 Str255 symName;
171 #if TARGET_CARBON
172 c2pstrcpy( (StringPtr) symName, name.fn_str() );
173 #else
174 strcpy( (char *)symName, name.fn_str() );
175 c2pstr( (char *)symName );
176 #endif
177 if( FindSymbol( m_handle, symName, &symAddress, &symClass ) == noErr )
178 symbol = (void *)symAddress;
179 #elif defined(__WXPM__) || defined(__EMX__)
180 DosQueryProcAddr( m_handle, 1L, (PSZ)name.c_str(), (PFN*)symbol );
181 #else
182 symbol = RawGetSymbol(m_handle, name);
183 #endif
184
185 if ( success )
186 *success = symbol != NULL;
187
188 return symbol;
189 }
190
191 void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
192 {
193 void *symbol = DoGetSymbol(name, success);
194 if ( !symbol )
195 {
196 #ifdef wxHAVE_DYNLIB_ERROR
197 Error();
198 #else
199 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
200 name.c_str());
201 #endif
202 }
203
204 return symbol;
205 }
206
207 // ----------------------------------------------------------------------------
208 // informational methods
209 // ----------------------------------------------------------------------------
210
211 /*static*/
212 wxString
213 wxDynamicLibrary::CanonicalizeName(const wxString& name,
214 wxDynamicLibraryCategory cat)
215 {
216 wxString nameCanonic;
217
218 // under Unix the library names usually start with "lib" prefix, add it
219 #if defined(__UNIX__) && !defined(__EMX__)
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 }
235 #else // !__UNIX__
236 wxUnusedVar(cat);
237 #endif // __UNIX__/!__UNIX__
238
239 nameCanonic << name << GetDllExt();
240 return nameCanonic;
241 }
242
243 /*static*/
244 wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
245 wxPluginCategory cat)
246 {
247 wxString suffix;
248 if ( cat == wxDL_PLUGIN_GUI )
249 {
250 wxAppTraits *traits = wxAppConsole::GetInstance() ?
251 wxAppConsole::GetInstance()->GetTraits() : NULL;
252 wxASSERT_MSG( traits,
253 _("can't query for GUI plugins name in console applications") );
254 suffix = traits->GetToolkitInfo().shortName;
255 }
256 #if wxUSE_UNICODE
257 suffix << _T('u');
258 #endif
259 #ifdef __WXDEBUG__
260 suffix << _T('d');
261 #endif
262
263 if ( !suffix.empty() )
264 suffix = wxString(_T("_")) + suffix;
265
266 #define WXSTRINGIZE(x) #x
267 #if defined(__UNIX__) && !defined(__EMX__)
268 #if (wxMINOR_VERSION % 2) == 0
269 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y)
270 #else
271 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
272 #endif
273 #else
274 #if (wxMINOR_VERSION % 2) == 0
275 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
276 #else
277 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
278 #endif
279 #endif
280
281 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
282 wxRELEASE_NUMBER));
283 #undef wxDLLVER
284 #undef WXSTRINGIZE
285
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
299 return CanonicalizeName(name + suffix, wxDL_MODULE);
300 }
301
302 /*static*/
303 wxString wxDynamicLibrary::GetPluginsDirectory()
304 {
305 #ifdef __UNIX__
306 wxString format = wxGetInstallPrefix();
307 wxString dir;
308 format << wxFILE_SEP_PATH
309 << wxT("lib") << wxFILE_SEP_PATH
310 << wxT("wx") << wxFILE_SEP_PATH
311 #if (wxMINOR_VERSION % 2) == 0
312 << wxT("%i.%i");
313 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
314 #else
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__
322 return wxEmptyString;
323 #endif
324 }
325
326
327 #endif // wxUSE_DYNLIB_CLASS