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