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" 
  29 #if wxUSE_DYNLIB_CLASS 
  31 #include "wx/dynlib.h" 
  32 #include "wx/filefn.h" 
  35 #include "wx/tokenzr.h" 
  37 // ---------------------------------------------------------------------------- 
  38 // conditional compilation 
  39 // ---------------------------------------------------------------------------- 
  41 #if defined(HAVE_DLOPEN) 
  42 #   define wxDllOpen(lib)                dlopen(lib.fn_str(), RTLD_NOW/*RTLD_LAZY*/) 
  43 #   define wxDllGetSymbol(handle, name)  dlsym(handle, name.mb_str()) 
  44 #   define wxDllClose                    dlclose 
  45 #elif defined(HAVE_SHL_LOAD) 
  46 #   define wxDllOpen(lib)                shl_load(lib.fn_str(), BIND_DEFERRED, 0) 
  47 #   define wxDllClose      shl_unload 
  49     static inline void *wxDllGetSymbol(shl_t handle
, const wxString
& name
) 
  52         if ( shl_findsym(&handle
, name
.mb_str(), TYPE_UNDEFINED
, &sym
) == 0 ) 
  57 #elif defined(__WINDOWS__) 
  60     // using LoadLibraryEx under Win32 to avoid name clash with LoadLibrary 
  62 #      define wxDllOpen(lib)                  ::LoadLibraryEx(lib, 0, 0) 
  64 #      define wxDllOpen(lib)                  ::LoadLibrary(lib) 
  66 #   define wxDllGetSymbol(handle, name)    ::GetProcAddress(handle, name) 
  67 #   define wxDllClose                      ::FreeLibrary 
  69 #elif defined(__OS2__) 
  73 #  define wxDllOpen(error, lib, handle)     DosLoadModule(error, sizeof(error), lib, &handle) 
  74 #  define wxDllGetSymbol(handle, modaddr)   DosQueryProcAddr(handle, 1L, NULL, (PFN*)modaddr) 
  75 #  define wxDllClose(handle)                DosFreeModule(handle) 
  77 #   error "Don't know how to load shared libraries on this platform." 
  80 // --------------------------------------------------------------------------- 
  82 // --------------------------------------------------------------------------- 
  84 wxLibraries wxTheLibraries
; 
  86 // ---------------------------------------------------------------------------- 
  88 // ---------------------------------------------------------------------------- 
  90 // construct the full name from the base shared object name: adds a .dll 
  91 // suffix under Windows or .so under Unix 
  92 static wxString 
ConstructLibraryName(const wxString
& basename
) 
  94     wxString 
fullname(basename
); 
  97 #   if defined(__HPUX__) 
 102 #elif defined(__WINDOWS__) || defined(__OS2__) 
 109 // ============================================================================ 
 111 // ============================================================================ 
 114 // --------------------------------------------------------------------------- 
 115 // wxLibrary (one instance per dynamic library) 
 116 // --------------------------------------------------------------------------- 
 118 wxLibrary::wxLibrary(wxDllType handle
) 
 120     typedef wxClassInfo 
*(*t_get_first
)(void); 
 121     t_get_first get_first
; 
 125     // Some system may use a local heap for library. 
 126     get_first 
= (t_get_first
)GetSymbol("wxGetClassFirst"); 
 127     // It is a wxWindows DLL. 
 129         PrepareClasses(get_first()); 
 132 wxLibrary::~wxLibrary() 
 136         wxDllClose(m_handle
); 
 140 wxObject 
*wxLibrary::CreateObject(const wxString
& name
) 
 142     wxClassInfo 
*info 
= (wxClassInfo 
*)classTable
.Get(name
); 
 147     return info
->CreateObject(); 
 150 void wxLibrary::PrepareClasses(wxClassInfo 
*first
) 
 152     // Index all class infos by their class name 
 153     wxClassInfo 
*info 
= first
; 
 156         if (info
->m_className
) 
 157             classTable
.Put(info
->m_className
, (wxObject 
*)info
); 
 158         info 
= info
->GetNext(); 
 161     // Set base pointers for each wxClassInfo 
 165         if (info
->GetBaseClassName1()) 
 166             info
->m_baseInfo1 
= (wxClassInfo 
*)classTable
.Get(info
->GetBaseClassName1()); 
 167         if (info
->GetBaseClassName2()) 
 168             info
->m_baseInfo2 
= (wxClassInfo 
*)classTable
.Get(info
->GetBaseClassName2()); 
 173 void *wxLibrary::GetSymbol(const wxString
& symbname
) 
 175    return wxDllLoader::GetSymbol(m_handle
, symbname
); 
 178 // --------------------------------------------------------------------------- 
 180 // --------------------------------------------------------------------------- 
 184 wxDllLoader::GetProgramHandle(void) 
 186 #if defined( HAVE_DLOPEN ) 
 187    // optain handle for main program 
 188    return dlopen(NULL
, RTLD_NOW
/*RTLD_LAZY*/);  
 189 #elif defined (HAVE_SHL_LOAD) 
 190    // shl_findsymbol with NULL handle looks up in main program 
 193 #warning "Please implement this for your system!" 
 194    wxFAIL_MSG(_("This method is not implemented under Windows or OS/2")); 
 201 wxDllLoader::LoadLibrary(const wxString 
& libname
, bool *success
) 
 205 #if defined(__WXMAC__) 
 210     wxMacPathToFSSpec( libname 
, &myFSSpec 
) ; 
 211     if (GetDiskFragment( &myFSSpec 
, 0 , kCFragGoesToEOF 
, "\p" , kPrivateCFragCopy 
, &handle 
, &myMainAddr 
, 
 212                 myErrName 
) != noErr 
) 
 214         p2cstr( myErrName 
) ; 
 215         wxASSERT_MSG( 1 , (char*)myErrName 
) ; 
 218 #elif defined(__OS2__) 
 219     char                            zError
[256] = ""; 
 220     wxDllOpen(zError
, libname
, handle
); 
 222     handle 
= wxDllOpen(libname
); 
 227         wxLogSysError(_("Failed to load shared library '%s'"), libname
.c_str()); 
 232         *success 
= handle 
!= 0; 
 241 wxDllLoader::UnloadLibrary(wxDllType handle
) 
 248 wxDllLoader::GetSymbol(wxDllType dllHandle
, const wxString 
&name
) 
 250     void *symbol 
= NULL
;    // return value 
 252 #if defined( __WXMAC__ ) 
 254     CFragSymbolClass symClass 
; 
 257     strcpy( (char*) symName 
, name 
) ; 
 258     c2pstr( (char*) symName 
) ; 
 260     if ( FindSymbol( dllHandle 
, symName 
, &symAddress 
, &symClass 
) == noErr 
) 
 261         symbol 
= (void *)symAddress 
; 
 262 #elif defined( __OS2__ ) 
 263     wxDllGetSymbol(dllHandle
, symbol
); 
 265     symbol 
= wxDllGetSymbol(dllHandle
, name
); 
 270         wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"), 
 276 // --------------------------------------------------------------------------- 
 277 // wxLibraries (only one instance should normally exist) 
 278 // --------------------------------------------------------------------------- 
 280 wxLibraries::wxLibraries() 
 284 wxLibraries::~wxLibraries() 
 286     wxNode 
*node 
= m_loaded
.First(); 
 289         wxLibrary 
*lib 
= (wxLibrary 
*)node
->Data(); 
 296 wxLibrary 
*wxLibraries::LoadLibrary(const wxString
& name
) 
 300     wxClassInfo 
*old_sm_first
; 
 302 #if defined(__VISAGECPP__) 
 303     node 
= m_loaded
.Find(name
.GetData()); 
 305         return ((wxLibrary 
*)node
->Data()); 
 307     if ( (node 
= m_loaded
.Find(name
.GetData())) ) 
 308         return ((wxLibrary 
*)node
->Data()); 
 310     // If DLL shares data, this is necessary. 
 311     old_sm_first 
= wxClassInfo::sm_first
; 
 312     wxClassInfo::sm_first 
= NULL
; 
 314     wxString libname 
= ConstructLibraryName(name
); 
 317   Unix automatically builds that library name, at least for dlopen() 
 320 #if defined(__UNIX__) 
 321     // found the first file in LD_LIBRARY_PATH with this name 
 322     wxString 
libPath("/lib:/usr/lib"); // system path first 
 323     const char *envLibPath 
= getenv("LD_LIBRARY_PATH"); 
 325         libPath 
<< ':' << envLibPath
; 
 326     wxStringTokenizer 
tokenizer(libPath
, _T(':')); 
 327     while ( tokenizer
.HasMoreToken() ) 
 329         wxString 
fullname(tokenizer
.NextToken()); 
 331         fullname 
<< '/' << libname
; 
 332         if ( wxFileExists(fullname
) ) 
 340     //else: not found in the path, leave the name as is (secutiry risk?) 
 345     bool success 
= FALSE
; 
 346     wxDllType handle 
= wxDllLoader::LoadLibrary(libname
, &success
); 
 349        lib 
= new wxLibrary(handle
); 
 350        wxClassInfo::sm_first 
= old_sm_first
; 
 351        m_loaded
.Append(name
.GetData(), lib
); 
 358 wxObject 
*wxLibraries::CreateObject(const wxString
& path
) 
 360     wxNode 
*node 
= m_loaded
.First(); 
 364         obj 
= ((wxLibrary 
*)node
->Data())->CreateObject(path
); 
 373 #endif // wxUSE_DYNLIB_CLASS