]>
Commit | Line | Data |
---|---|---|
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 | ||
34 | #ifndef WX_PRECOMP | |
35 | #include "wx/intl.h" | |
36 | #include "wx/log.h" | |
37 | #include "wx/app.h" | |
38 | #include "wx/utils.h" | |
39 | #endif //WX_PRECOMP | |
40 | ||
41 | #include "wx/filefn.h" | |
42 | #include "wx/filename.h" // for SplitPath() | |
43 | #include "wx/platinfo.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 wxString wxDynamicLibrary::ms_dllext(_T(".dll")); | |
63 | #endif | |
64 | ||
65 | // for MSW/Unix it is defined in platform-specific file | |
66 | #if !(defined(__WXMSW__) || defined(__UNIX__)) || defined(__EMX__) | |
67 | ||
68 | wxDllType wxDynamicLibrary::GetProgramHandle() | |
69 | { | |
70 | wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform")); | |
71 | return 0; | |
72 | } | |
73 | ||
74 | #endif // __WXMSW__ || __UNIX__ | |
75 | ||
76 | ||
77 | bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags) | |
78 | { | |
79 | wxASSERT_MSG(m_handle == 0, _T("Library already loaded.")); | |
80 | ||
81 | // add the proper extension for the DLL ourselves unless told not to | |
82 | wxString libname = libnameOrig; | |
83 | if ( !(flags & wxDL_VERBATIM) ) | |
84 | { | |
85 | // and also check that the libname doesn't already have it | |
86 | wxString ext; | |
87 | wxFileName::SplitPath(libname, NULL, NULL, &ext); | |
88 | if ( ext.empty() ) | |
89 | { | |
90 | libname += GetDllExt(); | |
91 | } | |
92 | } | |
93 | ||
94 | // different ways to load a shared library | |
95 | // | |
96 | // FIXME: should go to the platform-specific files! | |
97 | #if defined(__WXPM__) || defined(__EMX__) | |
98 | char err[256] = ""; | |
99 | DosLoadModule(err, sizeof(err), libname.c_str(), &m_handle); | |
100 | #else // this should be the only remaining branch eventually | |
101 | m_handle = RawLoad(libname, flags); | |
102 | #endif | |
103 | ||
104 | if ( m_handle == 0 && !(flags & wxDL_QUIET) ) | |
105 | { | |
106 | #ifdef wxHAVE_DYNLIB_ERROR | |
107 | Error(); | |
108 | #else | |
109 | wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str()); | |
110 | #endif | |
111 | } | |
112 | ||
113 | return IsLoaded(); | |
114 | } | |
115 | ||
116 | // for MSW and Unix this is implemented in the platform-specific file | |
117 | // | |
118 | // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp! | |
119 | #if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__) | |
120 | ||
121 | /* static */ | |
122 | void wxDynamicLibrary::Unload(wxDllType handle) | |
123 | { | |
124 | #if defined(__OS2__) || defined(__EMX__) | |
125 | DosFreeModule( handle ); | |
126 | #else | |
127 | #error "runtime shared lib support not implemented" | |
128 | #endif | |
129 | } | |
130 | ||
131 | #endif // !(__WXMSW__ || __UNIX__) | |
132 | ||
133 | void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const | |
134 | { | |
135 | wxCHECK_MSG( IsLoaded(), NULL, | |
136 | _T("Can't load symbol from unloaded library") ); | |
137 | ||
138 | void *symbol = 0; | |
139 | ||
140 | wxUnusedVar(symbol); | |
141 | #if defined(__WXPM__) || defined(__EMX__) | |
142 | DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol ); | |
143 | #else | |
144 | symbol = RawGetSymbol(m_handle, name); | |
145 | #endif | |
146 | ||
147 | if ( success ) | |
148 | *success = symbol != NULL; | |
149 | ||
150 | return symbol; | |
151 | } | |
152 | ||
153 | void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const | |
154 | { | |
155 | void *symbol = DoGetSymbol(name, success); | |
156 | if ( !symbol ) | |
157 | { | |
158 | #ifdef wxHAVE_DYNLIB_ERROR | |
159 | Error(); | |
160 | #else | |
161 | wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"), | |
162 | name.c_str()); | |
163 | #endif | |
164 | } | |
165 | ||
166 | return symbol; | |
167 | } | |
168 | ||
169 | // ---------------------------------------------------------------------------- | |
170 | // informational methods | |
171 | // ---------------------------------------------------------------------------- | |
172 | ||
173 | /*static*/ | |
174 | wxString | |
175 | wxDynamicLibrary::CanonicalizeName(const wxString& name, | |
176 | wxDynamicLibraryCategory cat) | |
177 | { | |
178 | wxString nameCanonic; | |
179 | ||
180 | // under Unix the library names usually start with "lib" prefix, add it | |
181 | #if defined(__UNIX__) && !defined(__EMX__) | |
182 | switch ( cat ) | |
183 | { | |
184 | default: | |
185 | wxFAIL_MSG( _T("unknown wxDynamicLibraryCategory value") ); | |
186 | // fall through | |
187 | ||
188 | case wxDL_MODULE: | |
189 | // don't do anything for modules, their names are arbitrary | |
190 | break; | |
191 | ||
192 | case wxDL_LIBRARY: | |
193 | // library names should start with "lib" under Unix | |
194 | nameCanonic = _T("lib"); | |
195 | break; | |
196 | } | |
197 | #else // !__UNIX__ | |
198 | wxUnusedVar(cat); | |
199 | #endif // __UNIX__/!__UNIX__ | |
200 | ||
201 | nameCanonic << name << GetDllExt(); | |
202 | return nameCanonic; | |
203 | } | |
204 | ||
205 | /*static*/ | |
206 | wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name, | |
207 | wxPluginCategory cat) | |
208 | { | |
209 | wxString suffix; | |
210 | if ( cat == wxDL_PLUGIN_GUI ) | |
211 | { | |
212 | suffix = wxPlatformInfo::Get().GetPortIdShortName(); | |
213 | } | |
214 | #if wxUSE_UNICODE | |
215 | suffix << _T('u'); | |
216 | #endif | |
217 | #ifdef __WXDEBUG__ | |
218 | suffix << _T('d'); | |
219 | #endif | |
220 | ||
221 | if ( !suffix.empty() ) | |
222 | suffix = wxString(_T("_")) + suffix; | |
223 | ||
224 | #define WXSTRINGIZE(x) #x | |
225 | #if defined(__UNIX__) && !defined(__EMX__) | |
226 | #if (wxMINOR_VERSION % 2) == 0 | |
227 | #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) | |
228 | #else | |
229 | #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z) | |
230 | #endif | |
231 | #else | |
232 | #if (wxMINOR_VERSION % 2) == 0 | |
233 | #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) | |
234 | #else | |
235 | #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z) | |
236 | #endif | |
237 | #endif | |
238 | ||
239 | suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION, | |
240 | wxRELEASE_NUMBER)); | |
241 | #undef wxDLLVER | |
242 | #undef WXSTRINGIZE | |
243 | ||
244 | #ifdef __WINDOWS__ | |
245 | // Add compiler identification: | |
246 | #if defined(__GNUG__) | |
247 | suffix << _T("_gcc"); | |
248 | #elif defined(__VISUALC__) | |
249 | suffix << _T("_vc"); | |
250 | #elif defined(__WATCOMC__) | |
251 | suffix << _T("_wat"); | |
252 | #elif defined(__BORLANDC__) | |
253 | suffix << _T("_bcc"); | |
254 | #endif | |
255 | #endif | |
256 | ||
257 | return CanonicalizeName(name + suffix, wxDL_MODULE); | |
258 | } | |
259 | ||
260 | /*static*/ | |
261 | wxString wxDynamicLibrary::GetPluginsDirectory() | |
262 | { | |
263 | #ifdef __UNIX__ | |
264 | wxString format = wxGetInstallPrefix(); | |
265 | wxString dir; | |
266 | format << wxFILE_SEP_PATH | |
267 | << wxT("lib") << wxFILE_SEP_PATH | |
268 | << wxT("wx") << wxFILE_SEP_PATH | |
269 | #if (wxMINOR_VERSION % 2) == 0 | |
270 | << wxT("%i.%i"); | |
271 | dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION); | |
272 | #else | |
273 | << wxT("%i.%i.%i"); | |
274 | dir.Printf(format.c_str(), | |
275 | wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER); | |
276 | #endif | |
277 | return dir; | |
278 | ||
279 | #else // ! __UNIX__ | |
280 | return wxEmptyString; | |
281 | #endif | |
282 | } | |
283 | ||
284 | ||
285 | #endif // wxUSE_DYNLIB_CLASS |