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