OpenWalnut
1.4.0
|
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