]> git.saurik.com Git - wxWidgets.git/blob - src/common/dynlib.cpp
Don't reset m_fp if wxFFile::Open() fails.
[wxWidgets.git] / src / common / dynlib.cpp
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 // Copyright: (c) 1998 Guilhem Lavaux
8 // 2000-2005 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //FIXME: This class isn't really common at all, it should be moved into
13 // platform dependent files (already done for Windows and Unix)
14
15 // ============================================================================
16 // declarations
17 // ============================================================================
18
19 // ----------------------------------------------------------------------------
20 // headers
21 // ----------------------------------------------------------------------------
22
23 #include "wx/wxprec.h"
24
25 #ifdef __BORLANDC__
26 #pragma hdrstop
27 #endif
28
29 #if wxUSE_DYNLIB_CLASS
30
31 #include "wx/dynlib.h"
32
33 #ifndef WX_PRECOMP
34 #include "wx/intl.h"
35 #include "wx/log.h"
36 #include "wx/app.h"
37 #include "wx/utils.h"
38 #endif //WX_PRECOMP
39
40 #include "wx/filefn.h"
41 #include "wx/filename.h" // for SplitPath()
42 #include "wx/platinfo.h"
43
44 #include "wx/arrimpl.cpp"
45
46 WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray)
47
48 // ============================================================================
49 // implementation
50 // ============================================================================
51
52 // ---------------------------------------------------------------------------
53 // wxDynamicLibrary
54 // ---------------------------------------------------------------------------
55
56 // for MSW/Unix it is defined in platform-specific file
57 #if !(defined(__WINDOWS__) || defined(__UNIX__)) || defined(__EMX__)
58
59 wxDllType wxDynamicLibrary::GetProgramHandle()
60 {
61 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
62 return 0;
63 }
64
65 #endif // __WINDOWS__ || __UNIX__
66
67
68 bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
69 {
70 wxASSERT_MSG(m_handle == 0, wxT("Library already loaded."));
71
72 // add the proper extension for the DLL ourselves unless told not to
73 wxString libname = libnameOrig;
74 if ( !(flags & wxDL_VERBATIM) )
75 {
76 // and also check that the libname doesn't already have it
77 wxString ext;
78 wxFileName::SplitPath(libname, NULL, NULL, &ext);
79 if ( ext.empty() )
80 {
81 libname += GetDllExt(wxDL_MODULE);
82 }
83 }
84
85 // different ways to load a shared library
86 //
87 // FIXME: should go to the platform-specific files!
88 #if defined(__WXPM__) || defined(__EMX__)
89 char err[256] = "";
90 DosLoadModule(err, sizeof(err), libname.c_str(), &m_handle);
91 #else // this should be the only remaining branch eventually
92 m_handle = RawLoad(libname, flags);
93 #endif
94
95 if ( m_handle == 0 && !(flags & wxDL_QUIET) )
96 {
97 #ifdef wxHAVE_DYNLIB_ERROR
98 Error();
99 #else
100 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
101 #endif
102 }
103
104 return IsLoaded();
105 }
106
107 // for MSW and Unix this is implemented in the platform-specific file
108 //
109 // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp!
110 #if (!defined(__WINDOWS__) && !defined(__UNIX__)) || defined(__EMX__)
111
112 /* static */
113 void wxDynamicLibrary::Unload(wxDllType handle)
114 {
115 #if defined(__OS2__) || defined(__EMX__)
116 DosFreeModule( handle );
117 #else
118 #error "runtime shared lib support not implemented"
119 #endif
120 }
121
122 #endif // !(__WINDOWS__ || __UNIX__)
123
124 void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
125 {
126 wxCHECK_MSG( IsLoaded(), NULL,
127 wxT("Can't load symbol from unloaded library") );
128
129 void *symbol = 0;
130
131 wxUnusedVar(symbol);
132 #if defined(__WXPM__) || defined(__EMX__)
133 DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol );
134 #else
135 symbol = RawGetSymbol(m_handle, name);
136 #endif
137
138 if ( success )
139 *success = symbol != NULL;
140
141 return symbol;
142 }
143
144 void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
145 {
146 void *symbol = DoGetSymbol(name, success);
147 if ( !symbol )
148 {
149 #ifdef wxHAVE_DYNLIB_ERROR
150 Error();
151 #else
152 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
153 name.c_str());
154 #endif
155 }
156
157 return symbol;
158 }
159
160 // ----------------------------------------------------------------------------
161 // informational methods
162 // ----------------------------------------------------------------------------
163
164 /*static*/
165 wxString wxDynamicLibrary::GetDllExt(wxDynamicLibraryCategory cat)
166 {
167 wxUnusedVar(cat);
168 #if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
169 return ".dll";
170 #elif defined(__HPUX__)
171 return ".sl";
172 #elif defined(__DARWIN__)
173 switch ( cat )
174 {
175 case wxDL_LIBRARY:
176 return ".dylib";
177 case wxDL_MODULE:
178 return ".bundle";
179 }
180 wxFAIL_MSG("unreachable");
181 return wxString(); // silence gcc warning
182 #else
183 return ".so";
184 #endif
185 }
186
187 /*static*/
188 wxString
189 wxDynamicLibrary::CanonicalizeName(const wxString& name,
190 wxDynamicLibraryCategory cat)
191 {
192 wxString nameCanonic;
193
194 // under Unix the library names usually start with "lib" prefix, add it
195 #if defined(__UNIX__) && !defined(__EMX__)
196 switch ( cat )
197 {
198 case wxDL_LIBRARY:
199 // Library names should start with "lib" under Unix.
200 nameCanonic = "lib";
201 break;
202 case wxDL_MODULE:
203 // Module names are arbitrary and should have no prefix added.
204 break;
205 }
206 #endif
207
208 nameCanonic << name << GetDllExt(cat);
209
210 return nameCanonic;
211 }
212
213 /*static*/
214 wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
215 wxPluginCategory cat)
216 {
217 wxString suffix;
218 if ( cat == wxDL_PLUGIN_GUI )
219 {
220 suffix = wxPlatformInfo::Get().GetPortIdShortName();
221 }
222 #if wxUSE_UNICODE
223 suffix << wxT('u');
224 #endif
225 #ifdef __WXDEBUG__
226 suffix << wxT('d');
227 #endif
228
229 if ( !suffix.empty() )
230 suffix = wxString(wxT("_")) + suffix;
231
232 #define WXSTRINGIZE(x) #x
233 #if defined(__UNIX__) && !defined(__EMX__)
234 #if (wxMINOR_VERSION % 2) == 0
235 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y)
236 #else
237 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
238 #endif
239 #else
240 #if (wxMINOR_VERSION % 2) == 0
241 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
242 #else
243 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
244 #endif
245 #endif
246
247 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
248 wxRELEASE_NUMBER));
249 #undef wxDLLVER
250 #undef WXSTRINGIZE
251
252 #ifdef __WINDOWS__
253 // Add compiler identification:
254 #if defined(__GNUG__)
255 suffix << wxT("_gcc");
256 #elif defined(__VISUALC__)
257 suffix << wxT("_vc");
258 #elif defined(__WATCOMC__)
259 suffix << wxT("_wat");
260 #elif defined(__BORLANDC__)
261 suffix << wxT("_bcc");
262 #endif
263 #endif
264
265 return CanonicalizeName(name + suffix, wxDL_MODULE);
266 }
267
268 /*static*/
269 wxString wxDynamicLibrary::GetPluginsDirectory()
270 {
271 #ifdef __UNIX__
272 wxString format = wxGetInstallPrefix();
273 wxString dir;
274 format << wxFILE_SEP_PATH
275 << wxT("lib") << wxFILE_SEP_PATH
276 << wxT("wx") << wxFILE_SEP_PATH
277 #if (wxMINOR_VERSION % 2) == 0
278 << wxT("%i.%i");
279 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
280 #else
281 << wxT("%i.%i.%i");
282 dir.Printf(format.c_str(),
283 wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER);
284 #endif
285 return dir;
286
287 #else // ! __UNIX__
288 return wxEmptyString;
289 #endif
290 }
291
292
293 #endif // wxUSE_DYNLIB_CLASS