1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Dynamic library management 
   4 // Author:      Guilhem Lavaux 
   8 // Copyright:   (c) Guilhem Lavaux 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21 #   pragma implementation "dynlib.h" 
  24 #include  "wx/wxprec.h" 
  30 #if wxUSE_DYNLIB_CLASS 
  32 #include "wx/dynlib.h" 
  33 #include "wx/filefn.h" 
  36 #include "wx/tokenzr.h" 
  38 // ---------------------------------------------------------------------------- 
  39 // conditional compilation 
  40 // ---------------------------------------------------------------------------- 
  42 #if defined(HAVE_DLOPEN) 
  43 #   define wxDllOpen(lib)                dlopen(lib.fn_str(), RTLD_NOW/*RTLD_LAZY*/) 
  44 #   define wxDllGetSymbol(handle, name)  dlsym(handle, name.mb_str()) 
  45 #   define wxDllClose                    dlclose 
  46 #elif defined(HAVE_SHL_LOAD) 
  47 #   define wxDllOpen(lib)                shl_load(lib.fn_str(), BIND_DEFERRED, 0) 
  48 #   define wxDllClose      shl_unload 
  50     static inline void *wxDllGetSymbol(shl_t handle
, const wxString
& name
) 
  53         if ( shl_findsym(&handle
, name
.mb_str(), TYPE_UNDEFINED
, &sym
) == 0 ) 
  58 #elif defined(__WINDOWS__) 
  61     // using LoadLibraryEx under Win32 to avoid name clash with LoadLibrary 
  63 #      define wxDllOpen(lib)                  ::LoadLibraryEx(lib, 0, 0) 
  65 #      define wxDllOpen(lib)                  ::LoadLibrary(lib) 
  67 #   define wxDllGetSymbol(handle, name)    ::GetProcAddress(handle, name) 
  68 #   define wxDllClose                      ::FreeLibrary 
  70 #   error "Don't know how to load shared libraries on this platform." 
  73 // --------------------------------------------------------------------------- 
  75 // --------------------------------------------------------------------------- 
  77 wxLibraries wxTheLibraries
; 
  79 // ---------------------------------------------------------------------------- 
  81 // ---------------------------------------------------------------------------- 
  83 // construct the full name from the base shared object name: adds a .dll 
  84 // suffix under Windows or .so under Unix 
  85 static wxString 
ConstructLibraryName(const wxString
& basename
) 
  87     wxString 
fullname(basename
); 
  90 #   if defined(__HPUX__) 
  95 #elif defined(__WINDOWS__) 
 102 // ============================================================================ 
 104 // ============================================================================ 
 107 // --------------------------------------------------------------------------- 
 108 // wxLibrary (one instance per dynamic library) 
 109 // --------------------------------------------------------------------------- 
 111 wxLibrary::wxLibrary(wxDllType handle
) 
 113     typedef wxClassInfo 
*(*t_get_first
)(void); 
 114     t_get_first get_first
; 
 118     // Some system may use a local heap for library. 
 119     get_first 
= (t_get_first
)GetSymbol("wxGetClassFirst"); 
 120     // It is a wxWindows DLL. 
 122         PrepareClasses(get_first()); 
 125 wxLibrary::~wxLibrary() 
 129         wxDllClose(m_handle
); 
 133 wxObject 
*wxLibrary::CreateObject(const wxString
& name
) 
 135     wxClassInfo 
*info 
= (wxClassInfo 
*)classTable
.Get(name
); 
 140     return info
->CreateObject(); 
 143 void wxLibrary::PrepareClasses(wxClassInfo 
*first
) 
 145     // Index all class infos by their class name 
 146     wxClassInfo 
*info 
= first
; 
 149         if (info
->m_className
) 
 150             classTable
.Put(info
->m_className
, (wxObject 
*)info
); 
 151         info 
= info
->GetNext(); 
 154     // Set base pointers for each wxClassInfo 
 158         if (info
->GetBaseClassName1()) 
 159             info
->m_baseInfo1 
= (wxClassInfo 
*)classTable
.Get(info
->GetBaseClassName1()); 
 160         if (info
->GetBaseClassName2()) 
 161             info
->m_baseInfo2 
= (wxClassInfo 
*)classTable
.Get(info
->GetBaseClassName2()); 
 166 void *wxLibrary::GetSymbol(const wxString
& symbname
) 
 168    return wxDllLoader::GetSymbol(m_handle
, symbname
); 
 171 // --------------------------------------------------------------------------- 
 173 // --------------------------------------------------------------------------- 
 177 wxDllLoader::GetProgramHandle(void) 
 180    return dlopen(NULL
, RTLD_NOW
/*RTLD_LAZY*/); 
 182 #pragma warning "Not implemented, please fix!" 
 190 wxDllLoader::LoadLibrary(const wxString 
& lib_name
, bool *success
) 
 196 #if defined(__WXMAC__) 
 201    wxMacPathToFSSpec( lib_name 
, &myFSSpec 
) ; 
 202    if (GetDiskFragment( &myFSSpec 
, 0 , kCFragGoesToEOF 
, "\p" , kPrivateCFragCopy 
, &handle 
, &myMainAddr 
, 
 203                         myErrName 
) != noErr 
) 
 205       p2cstr( myErrName 
) ; 
 206       wxASSERT_MSG( 1 , (char*)myErrName 
) ; 
 210    handle 
= wxDllOpen(lib_name
); 
 215       wxLogSysError(_("Failed to load shared library '%s'"), 
 226 wxDllLoader::GetSymbol(wxDllType dllHandle
, const wxString 
&name
) 
 228    void *symbol 
= NULL
;    // return value 
 230 #if defined( __WXMAC__ ) 
 232    CFragSymbolClass symClass 
; 
 235    strcpy( (char*) symName 
, name 
) ; 
 236    c2pstr( (char*) symName 
) ; 
 238    if ( FindSymbol( dllHandle 
, symName 
, &symAddress 
, &symClass 
) == noErr 
) 
 239       symbol 
= (void *)symAddress 
;  
 241     symbol 
= wxDllGetSymbol(dllHandle
, name
); 
 246        wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"), 
 252 // --------------------------------------------------------------------------- 
 253 // wxLibraries (only one instance should normally exist) 
 254 // --------------------------------------------------------------------------- 
 256 wxLibraries::wxLibraries() 
 260 wxLibraries::~wxLibraries() 
 262     wxNode 
*node 
= m_loaded
.First(); 
 265         wxLibrary 
*lib 
= (wxLibrary 
*)node
->Data(); 
 272 wxLibrary 
*wxLibraries::LoadLibrary(const wxString
& name
) 
 276     wxClassInfo 
*old_sm_first
; 
 278     if ( (node 
= m_loaded
.Find(name
.GetData())) ) 
 279         return ((wxLibrary 
*)node
->Data()); 
 281     // If DLL shares data, this is necessary. 
 282     old_sm_first 
= wxClassInfo::sm_first
; 
 283     wxClassInfo::sm_first 
= NULL
; 
 285     wxString lib_name 
= ConstructLibraryName(name
); 
 288   Unix automatically builds that library name, at least for dlopen() 
 291 #if defined(__UNIX__) 
 292     // found the first file in LD_LIBRARY_PATH with this name 
 293     wxString 
libPath("/lib:/usr/lib"); // system path first 
 294     const char *envLibPath 
= getenv("LD_LIBRARY_PATH"); 
 296         libPath 
<< ':' << envLibPath
; 
 297     wxStringTokenizer 
tokenizer(libPath
, _T(':')); 
 298     while ( tokenizer
.HasMoreToken() ) 
 300         wxString 
fullname(tokenizer
.NextToken()); 
 302         fullname 
<< '/' << lib_name
; 
 303         if ( wxFileExists(fullname
) ) 
 311     //else: not found in the path, leave the name as is (secutiry risk?) 
 316     bool success 
= FALSE
; 
 317     wxDllType handle 
= wxDllLoader::LoadLibrary(lib_name
, &success
); 
 320        lib 
= new wxLibrary(handle
); 
 321        wxClassInfo::sm_first 
= old_sm_first
; 
 322        m_loaded
.Append(name
.GetData(), lib
); 
 329 wxObject 
*wxLibraries::CreateObject(const wxString
& path
) 
 331     wxNode 
*node 
= m_loaded
.First(); 
 335         obj 
= ((wxLibrary 
*)node
->Data())->CreateObject(path
); 
 344 #endif // wxUSE_DYNLIB_CLASS