dll.hh
Go to the documentation of this file.
00001 // Copyright Vladimir Prus 2004.
00002 // Distributed under the Boost Software License, Version 1.0.
00003 // (See accompanying file LICENSE_1_0.txt
00004 // or copy at http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 #ifndef BOOST_DLL_HPP_VP_2004_08_24
00007 #define BOOST_DLL_HPP_VP_2004_08_24
00008 
00009 #include <string>
00010 #include <stdexcept>
00011 #include <boost/shared_ptr.hpp>
00012 #include <boost/bind.hpp>
00013 #include <boost/type_traits/remove_pointer.hpp>
00014 
00015 // FIXME: that's for Linux only
00016 #include <dlfcn.h> 
00017 
00018 #include <iostream>
00019 
00020 namespace utilmm { namespace plugin {
00021 
00022     struct killer 
00023     {
00024         killer(void* h) : h(h) {}
00025         template<class T>
00026         void operator()(T)
00027         {
00028             std::cout << "Killing DLL\n";
00029             dlclose(h);
00030         }
00031         void* h;
00032     };
00033 
00034     class dll {
00035     public:
00036         dll() {} // TODO: should remove this or make non-public
00037         dll(const std::string& name) : m_name(name) {}
00038 
00039         template<typename SymbolType>
00040         boost::shared_ptr<
00041             typename boost::remove_pointer<SymbolType>::type> 
00042         get(const std::string& symbol_name) const
00043         {
00044             // TODO: static assert that SymbolType is a pointer.
00045             typedef typename boost::remove_pointer<SymbolType>::type PointedType;
00046             
00047             // Open the library. Yes, we do it on every access to 
00048             // a symbol, see the design discussion in the documentation.
00049             void* handle = dlopen(m_name.c_str(), RTLD_LAZY|RTLD_GLOBAL);
00050             if (!handle) {
00051                 throw std::logic_error("Could not open DLL");
00052             }
00053             // Clear the error state.
00054             dlerror();
00055             void* address = dlsym(handle, symbol_name.c_str());
00056             char* error = dlerror();
00057             if (error) {
00058                 throw std::logic_error(error);
00059             }
00060             // Cast the to right type.
00061             SymbolType s = (SymbolType)(address);
00062 
00063             boost::shared_ptr<PointedType> result(s, 
00064                                                   //killer(handle));
00065                                                   boost::bind(dlclose, handle));
00066             
00067             return result;            
00068         }        
00069 
00070     private:
00071         std::string m_name;
00072     };
00073 
00074 }}
00075 
00076 #endif


utilmm
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:31