initial release
This commit is contained in:
		
							
								
								
									
										166
									
								
								mrw/dynamiclibrary.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								mrw/dynamiclibrary.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
/** @file
 | 
			
		||||
 | 
			
		||||
    $Id$
 | 
			
		||||
 | 
			
		||||
    $Date$
 | 
			
		||||
    $Author$
 | 
			
		||||
 | 
			
		||||
    @copy © Marc Wäckerlin
 | 
			
		||||
    @license LGPL, see file <a href="license.html">COPYING</a>
 | 
			
		||||
 | 
			
		||||
    $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 <ltdl.h>
 | 
			
		||||
#include <mrw/string.hpp>
 | 
			
		||||
#include <mrw/stdext.hpp>
 | 
			
		||||
#include <mrw/exception.hpp>
 | 
			
		||||
 | 
			
		||||
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(), "<none>")) {
 | 
			
		||||
          }
 | 
			
		||||
      };
 | 
			
		||||
      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
 | 
			
		||||
							
								
								
									
										47
									
								
								mrw/dynamiclibrary_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								mrw/dynamiclibrary_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/** @file
 | 
			
		||||
 | 
			
		||||
    $Id$
 | 
			
		||||
 | 
			
		||||
    $Date$
 | 
			
		||||
    $Author$
 | 
			
		||||
 | 
			
		||||
    @copy © Marc Wäckerlin
 | 
			
		||||
    @license LGPL, see file <a href="license.html">COPYING</a>
 | 
			
		||||
 | 
			
		||||
    $Log$
 | 
			
		||||
    Revision 1.1  2005/02/18 15:53:56  marc
 | 
			
		||||
    initial release
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
         1         2         3         4         5         6         7         8
 | 
			
		||||
    5678901234567890123456789012345678901234567890123456789012345678901234567890
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <mrw/dynamiclibrary.hpp>
 | 
			
		||||
#include <cppunit/TestFixture.h>
 | 
			
		||||
#include <cppunit/ui/text/TestRunner.h>
 | 
			
		||||
#include <cppunit/extensions/HelperMacros.h>
 | 
			
		||||
#include <cppunit/extensions/TestFactoryRegistry.h>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								mrw/dynamiclibrary_testlib.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								mrw/dynamiclibrary_testlib.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
/** @file
 | 
			
		||||
 | 
			
		||||
    $Id$
 | 
			
		||||
 | 
			
		||||
    $Date$
 | 
			
		||||
    $Author$
 | 
			
		||||
 | 
			
		||||
    @copy © Marc Wäckerlin
 | 
			
		||||
    @license LGPL, see file <a href="license.html">COPYING</a>
 | 
			
		||||
 | 
			
		||||
    $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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user