OpenWalnut  1.4.0
WSharedLib.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WSHAREDLIB_H
00026 #define WSHAREDLIB_H
00027 
00028 #include <algorithm>
00029 #include <string>
00030 
00031 #include <boost/filesystem.hpp>
00032 
00033 
00034 
00035 /**
00036  * This class loads shared libraries and provides function pointers. This is especially useful for dynamic loading of shared libraries during
00037  * runtime. This works on Windows, Linux and Mac OS and is based on the openbug shared_lib implementation by
00038  * Christian Heine <heine@informatik.uni-leipzig.de>. For more details, see http://www.informatik.uni-leipzig.de/~hg/openbug .
00039  *
00040  * \note This class performs locking so that under any system variables of shared_lib may be used in multi-threaded environments.
00041  * \warning Because the POSIX standard does not enforce thread safety for the functions dlopen, dlclose, dlerror, and dlsym, these should not
00042  *          be used simultaneously with variables of this class.
00043  */
00044 class WSharedLib // NOLINT
00045 {
00046 public:
00047     /**
00048      * Constructor. Loads the specified library.
00049      *
00050      * \param lib the library to load. Can be a DLL,SO or DYLIB (depending on system). This can be an absolut or relative path. Otherwise
00051      * standard library search directory may be searched.
00052      *
00053      * \note If the shared library is already loaded, this constructor just
00054      *       increases its reference count. This is detected even if different
00055      *       paths were used (e.g. "./somelib.so", "../libs/somelib.so").
00056      * \throw WLibraryLoadFailed if the lib could not be loaded. Maybe because of file not found or link errors.
00057      */
00058     explicit WSharedLib( boost::filesystem::path lib );
00059 
00060     /**
00061      * Copies this instance by increasing the reference counter of the loaded library by 1.
00062      *
00063      * \param rhs the other Lib.
00064      */
00065     WSharedLib( const WSharedLib& rhs );
00066 
00067     /**
00068      * Destructor. Decreases the reference counter and unloads the library if the reference count drops to zero.
00069      */
00070     virtual ~WSharedLib();
00071 
00072     /**
00073      * Copy assignment for shared libraries.
00074      *
00075      * \param rhs the one to assign
00076      *
00077      * \return this instance copied from the specified one.
00078      */
00079     WSharedLib& operator=( const WSharedLib& rhs );
00080 
00081     /**
00082      * Swap to shared libraries.
00083      *
00084      * \param lhs the one
00085      * \param rhs the other
00086      */
00087     friend
00088     void swap( WSharedLib& lhs, WSharedLib& rhs );
00089 
00090     /** Search for a function in the shared library.
00091      * \tparam FuncType a function type
00092      * \param name the name of the function
00093      * \param func will be set to the function pointer
00094      *
00095      * \throw WLibraryFetchFailed if the symbol was not found
00096      *
00097      * \warning type unsafe, make sure the symbol actually is of the proper type
00098      */
00099     template < typename FuncType >
00100     void fetchFunction( const std::string& name, FuncType& func ) const;
00101 
00102     /**
00103      * Check whether the function exists.
00104      *
00105      * \param name the name of the function
00106      *
00107      * \return true if it exists.
00108      */
00109     bool existsFunction( const std::string& name ) const;
00110 
00111     /** Search for an variable in the shared library
00112      * \tparam PtrType a pointer type
00113      * \param name the name of the variable
00114      * \param variable will be set to the variable pointer
00115      *
00116      * \throw WLibraryFetchFailed if the symbol was not found
00117      *
00118      * \warning type unsafe, make sure the symbol actually is of the proper type
00119      */
00120     template < typename PtrType >
00121     void fetchVariable( const std::string& name, PtrType& variable ) const;
00122 
00123     /**
00124      * Returns the prefix used for libraries on the system. On Unix this mostly is "lib".
00125      *
00126      * \return the prefix.
00127      */
00128     static std::string getSystemPrefix();
00129 
00130     /**
00131      * Returns the suffix for libraries used on the system. On Unix this mostly is "so", Windows uses "dll" and Mac something like "dylib".
00132      *
00133      * \return the suffix.
00134      */
00135     static std::string getSystemSuffix();
00136 
00137     /**
00138      * Returns the default path for libraries on the current system. This is the directory where to search for .so,.dll or .dylib files. On Unix,
00139      * this will be "../lib", on Windows ".".
00140      *
00141      * \return the path on the system.
00142      */
00143     static std::string getSystemLibPath();
00144 
00145     /**
00146      * Returns the filename of the library without path.
00147      *
00148      * \return the filename.
00149      */
00150     std::string getLibraryName();
00151 
00152 protected:
00153 private:
00154     //! neutral function pointer type
00155     typedef void (*func_ptr_type)(void);
00156 
00157     /**
00158      * Find the specified function pointer in the library.
00159      *
00160      * \param name the symbol to search
00161      *
00162      * \return the pointer to the symbol as function pointer
00163      */
00164     func_ptr_type findFunction( const std::string& name ) const;
00165 
00166     /**
00167      * Find the specified symbol in the library.
00168      *
00169      * \param name the symbol to search
00170      *
00171      * \return the pointer to the symbol as function pointer.
00172      */
00173     void* findVariable( const std::string& name ) const;
00174 
00175     //! internal data
00176     struct data;
00177 
00178     //! internal data
00179     data* m_data;
00180 
00181     //! path to lib
00182     boost::filesystem::path m_libPath;
00183 };
00184 
00185 template < typename FuncType >
00186 void WSharedLib::fetchFunction( const std::string& name, FuncType& func ) const
00187 {
00188     func = reinterpret_cast< FuncType >( findFunction( name ) );
00189 }
00190 
00191 template < typename PtrType >
00192 void WSharedLib::fetchVariable( const std::string& name, PtrType& variable ) const
00193 {
00194     variable = static_cast< PtrType >( findVariable( name ) );
00195 }
00196 
00197 #endif  // WSHAREDLIB_H
00198