1 /////////////////////////////////////////////////////////////////////////////
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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
25 # pragma implementation "dynlib.h"
28 #include "wx/wxprec.h"
34 #if wxUSE_DYNLIB_CLASS
36 #include "wx/dynlib.h"
37 #include "wx/filefn.h"
41 #include "wx/filename.h" // for SplitPath()
43 #include "wx/apptrait.h"
45 #include "wx/arrimpl.cpp"
47 #if defined(__WXMAC__)
48 #include "wx/mac/private.h"
51 WX_DEFINE_USER_EXPORTED_OBJARRAY(wxDynamicLibraryDetailsArray
);
53 // ============================================================================
55 // ============================================================================
57 // ---------------------------------------------------------------------------
59 // ---------------------------------------------------------------------------
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
;
67 // for MSW/Unix it is defined in platform-specific file
68 #if !(defined(__WXMSW__) || defined(__UNIX__)) || defined(__EMX__)
70 wxDllType
wxDynamicLibrary::GetProgramHandle()
72 wxFAIL_MSG( wxT("GetProgramHandle() is not implemented under this platform"));
76 #endif // __WXMSW__ || __UNIX__
79 bool wxDynamicLibrary::Load(const wxString
& libnameOrig
, int flags
)
81 wxASSERT_MSG(m_handle
== 0, _T("Library already loaded."));
83 // add the proper extension for the DLL ourselves unless told not to
84 wxString libname
= libnameOrig
;
85 if ( !(flags
& wxDL_VERBATIM
) )
87 // and also check that the libname doesn't already have it
89 wxFileName::SplitPath(libname
, NULL
, NULL
, &ext
);
92 libname
+= GetDllExt();
96 // different ways to load a shared library
98 // FIXME: should go to the platform-specific files!
99 #if defined(__WXMAC__) && !defined(__DARWIN__)
104 wxMacFilename2FSSpec( libname
, &myFSSpec
);
106 if( GetDiskFragment( &myFSSpec
,
113 myErrName
) != noErr
)
115 wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
117 wxMacMakeStringFromPascal( myErrName
).c_str() );
121 #elif defined(__WXPM__) || defined(__EMX__)
123 DosLoadModule(err
, sizeof(err
), libname
.c_str(), &m_handle
);
125 m_handle
= RawLoad(libname
, flags
);
130 #ifdef wxHAVE_DYNLIB_ERROR
133 wxLogSysError(_("Failed to load shared library '%s'"), libname
.c_str());
140 // for MSW and Unix this is implemented in the platform-specific file
142 // TODO: move the rest to os2/dlpm.cpp and mac/dlmac.cpp!
143 #if (!defined(__WXMSW__) && !defined(__UNIX__)) || defined(__EMX__)
146 void wxDynamicLibrary::Unload(wxDllType handle
)
148 #if defined(__WXPM__) || defined(__EMX__)
149 DosFreeModule( handle
);
150 #elif defined(__WXMAC__) && !defined(__DARWIN__)
151 CloseConnection( (CFragConnectionID
*) &handle
);
153 #error "runtime shared lib support not implemented"
157 #endif // !(__WXMSW__ || __UNIX__)
159 void *wxDynamicLibrary::DoGetSymbol(const wxString
&name
, bool *success
) const
161 wxCHECK_MSG( IsLoaded(), NULL
,
162 _T("Can't load symbol from unloaded library") );
167 #if defined(__WXMAC__) && !defined(__DARWIN__)
169 CFragSymbolClass symClass
;
172 c2pstrcpy( (StringPtr
) symName
, name
.fn_str() );
174 strcpy( (char *)symName
, name
.fn_str() );
175 c2pstr( (char *)symName
);
177 if( FindSymbol( m_handle
, symName
, &symAddress
, &symClass
) == noErr
)
178 symbol
= (void *)symAddress
;
179 #elif defined(__WXPM__) || defined(__EMX__)
180 DosQueryProcAddr( m_handle
, 1L, name
.c_str(), (PFN
*)symbol
);
182 symbol
= RawGetSymbol(m_handle
, name
);
186 *success
= symbol
!= NULL
;
191 void *wxDynamicLibrary::GetSymbol(const wxString
& name
, bool *success
) const
193 void *symbol
= DoGetSymbol(name
, success
);
196 #ifdef wxHAVE_DYNLIB_ERROR
199 wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
207 // ----------------------------------------------------------------------------
208 // informational methods
209 // ----------------------------------------------------------------------------
213 wxDynamicLibrary::CanonicalizeName(const wxString
& name
,
214 wxDynamicLibraryCategory cat
)
216 wxString nameCanonic
;
218 // under Unix the library names usually start with "lib" prefix, add it
219 #if defined(__UNIX__) && !defined(__EMX__)
223 wxFAIL_MSG( _T("unknown wxDynamicLibraryCategory value") );
227 // don't do anything for modules, their names are arbitrary
231 // library names should start with "lib" under Unix
232 nameCanonic
= _T("lib");
237 #endif // __UNIX__/!__UNIX__
239 nameCanonic
<< name
<< GetDllExt();
244 wxString
wxDynamicLibrary::CanonicalizePluginName(const wxString
& name
,
245 wxPluginCategory cat
)
248 if ( cat
== wxDL_PLUGIN_GUI
)
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
;
263 if ( !suffix
.empty() )
264 suffix
= wxString(_T("_")) + suffix
;
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)
271 #define wxDLLVER(x,y,z) "-" WXSTRINGIZE(x) "." WXSTRINGIZE(y) "." WXSTRINGIZE(z)
274 #if (wxMINOR_VERSION % 2) == 0
275 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y)
277 #define wxDLLVER(x,y,z) WXSTRINGIZE(x) WXSTRINGIZE(y) WXSTRINGIZE(z)
281 suffix
<< wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION
, wxMINOR_VERSION
,
287 // Add compiler identification:
288 #if defined(__GNUG__)
289 suffix
<< _T("_gcc");
290 #elif defined(__VISUALC__)
292 #elif defined(__WATCOMC__)
293 suffix
<< _T("_wat");
294 #elif defined(__BORLANDC__)
295 suffix
<< _T("_bcc");
299 return CanonicalizeName(name
+ suffix
, wxDL_MODULE
);
303 wxString
wxDynamicLibrary::GetPluginsDirectory()
306 wxString format
= wxGetInstallPrefix();
308 format
<< wxFILE_SEP_PATH
309 << wxT("lib") << wxFILE_SEP_PATH
310 << wxT("wx") << wxFILE_SEP_PATH
311 #if (wxMINOR_VERSION % 2) == 0
313 dir
.Printf(format
.c_str(), wxMAJOR_VERSION
, wxMINOR_VERSION
);
316 dir
.Printf(format
.c_str(),
317 wxMAJOR_VERSION
, wxMINOR_VERSION
, wxRELEASE_NUMBER
);
322 return wxEmptyString
;
327 #endif // wxUSE_DYNLIB_CLASS