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