1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dynlib.cpp
3 // Purpose: Dynamic library management
4 // Author: Guilhem Lavaux
8 // Copyright: (c) 1998 Guilhem Lavaux
9 // 2000-2005 Vadim Zeitlin
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
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)
16 // ============================================================================
18 // ============================================================================
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
24 #include "wx/wxprec.h"
30 #if wxUSE_DYNLIB_CLASS
32 #include "wx/dynlib.h"
33 #include "wx/filefn.h"
37 #include "wx/filename.h" // for SplitPath()
39 #include "wx/apptrait.h"
41 #include "wx/arrimpl.cpp"
43 #if defined(__WXMAC__)
44 #include "wx/mac/private.h"
47 WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray)
49 // ============================================================================
51 // ============================================================================
53 // ---------------------------------------------------------------------------
55 // ---------------------------------------------------------------------------
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;
63 // for MSW/Unix it is defined in platform-specific file
64 #if !(defined(__WXMSW__) || defined(__UNIX__)) || defined(__EMX__)
66 wxDllType wxDynamicLibrary::GetProgramHandle()
68 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
72 #endif // __WXMSW__ || __UNIX__
75 bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
77 wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
79 // add the proper extension for the DLL ourselves unless told not to
80 wxString libname = libnameOrig;
81 if ( !(flags & wxDL_VERBATIM) )
83 // and also check that the libname doesn't already have it
85 wxFileName::SplitPath(libname, NULL, NULL, &ext);
88 libname += GetDllExt();
92 // different ways to load a shared library
94 // FIXME: should go to the platform-specific files!
95 #if defined(__WXMAC__) && !defined(__DARWIN__)
100 wxMacFilename2FSSpec( libname , &myFSSpec );
102 if( GetDiskFragment( &myFSSpec,
109 myErrName ) != noErr )
111 wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
113 wxMacMakeStringFromPascal( myErrName ).c_str() );
117 #elif defined(__WXPM__) || defined(__EMX__)
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);
126 #ifdef wxHAVE_DYNLIB_ERROR
129 wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
136 // for MSW and Unix this is implemented in the platform-specific file
138 // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp!
139 #if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__)
142 void wxDynamicLibrary::Unload(wxDllType handle)
144 #if defined(__OS2__) || defined(__EMX__)
145 DosFreeModule( handle );
146 #elif defined(__WXMAC__) && !defined(__DARWIN__)
147 CloseConnection( (CFragConnectionID*) &handle );
149 #error "runtime shared lib support not implemented"
153 #endif // !(__WXMSW__ || __UNIX__)
155 void *wxDynamicLibrary::DoGetSymbol(const wxString &name, bool *success) const
157 wxCHECK_MSG( IsLoaded(), NULL,
158 _T("Can't load symbol from unloaded library") );
163 #if defined(__WXMAC__) && !defined(__DARWIN__)
165 CFragSymbolClass symClass;
168 c2pstrcpy( (StringPtr) symName, name.fn_str() );
170 strcpy( (char *)symName, name.fn_str() );
171 c2pstr( (char *)symName );
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 );
178 symbol = RawGetSymbol(m_handle, name);
182 *success = symbol != NULL;
187 void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
189 void *symbol = DoGetSymbol(name, success);
192 #ifdef wxHAVE_DYNLIB_ERROR
195 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
203 // ----------------------------------------------------------------------------
204 // informational methods
205 // ----------------------------------------------------------------------------
209 wxDynamicLibrary::CanonicalizeName(const wxString& name,
210 wxDynamicLibraryCategory cat)
212 wxString nameCanonic;
214 // under Unix the library names usually start with "lib" prefix, add it
215 #if defined(__UNIX__) && !defined(__EMX__)
219 wxFAIL_MSG( _T("unknown wxDynamicLibraryCategory value") );
223 // don't do anything for modules, their names are arbitrary
227 // library names should start with "lib" under Unix
228 nameCanonic = _T("lib");
233 #endif // __UNIX__/!__UNIX__
235 nameCanonic << name << GetDllExt();
240 wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
241 wxPluginCategory cat)
244 if ( cat == wxDL_PLUGIN_GUI )
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;
259 if ( !suffix.empty() )
260 suffix = wxString(_T("_")) + suffix;
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)
267 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
270 #if (wxMINOR_VERSION % 2) == 0
271 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
273 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
277 suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
283 // Add compiler identification:
284 #if defined(__GNUG__)
285 suffix << _T("_gcc");
286 #elif defined(__VISUALC__)
288 #elif defined(__WATCOMC__)
289 suffix << _T("_wat");
290 #elif defined(__BORLANDC__)
291 suffix << _T("_bcc");
295 return CanonicalizeName(name + suffix, wxDL_MODULE);
299 wxString wxDynamicLibrary::GetPluginsDirectory()
302 wxString format = wxGetInstallPrefix();
304 format << wxFILE_SEP_PATH
305 << wxT("lib") << wxFILE_SEP_PATH
306 << wxT("wx") << wxFILE_SEP_PATH
307 #if (wxMINOR_VERSION % 2) == 0
309 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
312 dir.Printf(format.c_str(),
313 wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER);
318 return wxEmptyString;
323 #endif // wxUSE_DYNLIB_CLASS