parent
4d0af6ae04
commit
190b0c58ce
3 changed files with 237 additions and 0 deletions
@ -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 |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue