/** @file $Id$ $Date$ $Author$ @copy © Marc Wäckerlin @license LGPL, see file COPYING $Log$ Revision 1.1 2005/02/18 15:53:56 marc initial release 1 2 3 4 5 6 7 8 5678901234567890123456789012345678901234567890123456789012345678901234567890 */ #ifndef __MRW_DYNAMICLIBRARY_HPP__ #define __MRW_DYNAMICLIBRARY_HPP__ #include #include #include #include namespace mrw { class DynamicLibrary { public: class failure: public mrw::runtime_error { public: failure(const std::string& arg) throw(std::bad_exception): mrw::runtime_error("DynamicLibrary failure "+arg +"; ltdl reason: "+ +mrw::ifelse(lt_dlerror(), "")) { } }; class Lib { Lib() throw(): _lib(0) {} Lib(const std::string& lib) throw(std::exception): _lib(0) { open(lib); } ~Lib() throw() { try {close();} catch(...) {} } operator bool() throw() { return _lib; } Lib& open(const std::string& lib) throw(std::exception) { close(); if (!(_lib = lt_dlopenext(lib.c_str()))) throw failure("cannot open dynamic library "+lib); return *this; } Lib& close() throw(std::exception) { if (_lib && lt_dlclose(_lib)!=0) throw failure("cannot close dynamic library"); _lib = 0; return *this; } private: friend class DynamicLibrary; lt_dlhandle handle() throw(std::exception) { if (!_lib) throw failure("library not open"); return _lib; } private: lt_dlhandle _lib; }; public: DynamicLibrary() throw(std::exception): _opened(false) { if (lt_dlinit()>0) throw failure("cannot initialize dynamic library loader"); _opened = true; } DynamicLibrary(const std::string& lib) throw(std::exception): _opened(false) { if (lt_dlinit()>0) throw failure("cannot initialize dynamic library loader"); _opened = true; _lib.open(lib); } ~DynamicLibrary() throw() { try {close();} catch (...) {} if (_opened) lt_dlexit(); } DynamicLibrary& open(const std::string& lib) throw(std::exception) { _lib.open(lib); return *this; } DynamicLibrary& close() throw(std::exception) { _lib.close(); return *this; } DynamicLibrary& resident() throw(std::exception) { if (lt_dlmakeresident(_lib.handle())!=0) throw failure("cannot make library resident"); return *this; } bool isResident() throw(std::exception) { return lt_dlisresident(_lib.handle())==1; } lt_ptr symbol(const std::string& name) throw(std::exception) { lt_ptr sym(lt_dlsym(_lib.handle(), name.c_str())); if (!sym) throw failure("cannot load dynamic library symbol: "+name); return sym; } /** {{"name1", &name1}, {"name2", &name2}, 0} */ DynamicLibrary& preload(const lt_dlsymlist* symbols) throw(std::exception) { if (lt_dlpreload(symbols)!=0) throw failure("error in preloading libraries"); return *this; } /** {{"name1", &name1}, {"name2", &name2}, 0} */ DynamicLibrary& preloadDefault(const lt_dlsymlist* symbols) throw(std::exception) { if (lt_dlpreload_default(symbols)!=0) throw failure("error in preloading libraries"); return *this; } int foreachfile(const char* searchPath, int(*function)(const char*, lt_ptr), lt_ptr data) throw() { return lt_dlforeachfile(searchPath, function, data); } /// @todo enable // static void preloadedSymbols(const std::string& lib, // const lt_dlsymlist symbols[]) // throw(std::exception) { // Lib lib(lt_dlopenext(lib.c_str())); // LTDL_SET_PRELOADED_SYMBOLS(symbols); // } static void addSearchDir(const std::string& dir) throw(std::exception) { if (lt_dladdsearchdir(dir.c_str())!=0) throw failure("cannot add search dir: "+dir); } static void insertSearchDir(const std::string& before, const std::string& dir) throw(std::exception) { if (lt_dlinsertsearchdir(before.c_str(), dir.c_str())!=0) throw failure("cannot add search dir: "+dir); } /// @todo enable // static std::string void setSearchPath(const std::string& dir) throw() { // char const * const path(lt_dlgetsearchpath()); // if (!path) // throw failure("cannot get search path"); // return path; // } private: bool _opened; Lib _lib; }; } #endif