diff --git a/mrw/dynamiclibrary.hpp b/mrw/dynamiclibrary.hpp
new file mode 100644
index 0000000..6cec2b5
--- /dev/null
+++ b/mrw/dynamiclibrary.hpp
@@ -0,0 +1,166 @@
+/** @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
diff --git a/mrw/dynamiclibrary_test.cpp b/mrw/dynamiclibrary_test.cpp
new file mode 100644
index 0000000..51d7b11
--- /dev/null
+++ b/mrw/dynamiclibrary_test.cpp
@@ -0,0 +1,47 @@
+/** @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
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+class DynamicLibraryTest: public CppUnit::TestFixture {
+ public:
+ void Load() {
+ mrw::DynamicLibrary lib("libdynamiclibrary_testlib");
+ int(*test1)(int) = (int(*)(int))lib.symbol("test1");
+ CPPUNIT_ASSERT((*test1)(2)==4);
+ }
+ void LoadError() {
+ mrw::DynamicLibrary lib("DASist-Sicher_Keine_DynamischePHIPLIOTEEK!!!");
+ }
+ CPPUNIT_TEST_SUITE(DynamicLibraryTest);
+ CPPUNIT_TEST(Load);
+ CPPUNIT_TEST_EXCEPTION(LoadError, mrw::DynamicLibrary::failure);
+ CPPUNIT_TEST_SUITE_END();
+};
+CPPUNIT_TEST_SUITE_REGISTRATION(DynamicLibraryTest);
+
+int main() {
+ CppUnit::TextUi::TestRunner runner;
+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+ return runner.run() ? 0 : 1;
+}
diff --git a/mrw/dynamiclibrary_testlib.cpp b/mrw/dynamiclibrary_testlib.cpp
new file mode 100644
index 0000000..63479b4
--- /dev/null
+++ b/mrw/dynamiclibrary_testlib.cpp
@@ -0,0 +1,24 @@
+/** @file
+
+ $Id$
+
+ $Date$
+ $Author$
+
+ @copy © Marc Wäckerlin
+ @license LGPL, see file COPYING
+
+ $Log$
+ Revision 1.1 2005/02/18 15:53:55 marc
+ initial release
+
+
+ 1 2 3 4 5 6 7 8
+ 5678901234567890123456789012345678901234567890123456789012345678901234567890
+*/
+
+extern "C" {
+ int test1(int i) {
+ return i*i;
+ }
+}