casa
$Rev:20696$
|
00001 //# DynLib.h: Class to handle loadig of dynamic libraries 00002 //# Copyright (C) 2009 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: DynLib.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $ 00027 00028 #ifndef CASA_DYNLIB_H 00029 #define CASA_DYNLIB_H 00030 00031 //# Includes 00032 #include <casa/aips.h> 00033 #include <string> 00034 00035 namespace casa { //# NAMESPACE CASA - BEGIN 00036 00037 // <summary> 00038 // Class to handle loadig of dynamic libraries 00039 // </summary> 00040 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos=""> 00041 // </reviewed> 00042 00043 // <use visibility=export> 00044 00045 // <prerequisite> 00046 // <li> Basic knowledge of the dlopen function family 00047 // </prerequisite> 00048 00049 // <synopsis> 00050 // This class makes it possible to load a dynamic library and execute an 00051 // initialization function. Furthermore one can get a pointer to any function 00052 // in the dynamic library and close the library. 00053 // 00054 // It is a wrapper around functions dlopen, dlsym, and dlclose. 00055 // 00056 // If dlopen and so is not supported on a platform, the class acts as if 00057 // the shared library could not be found. 00058 // </synopsis> 00059 00060 // <example> 00061 // <srcblock> 00062 // DynLib dl("bitflagsengine", "register_bitflagsengine"); 00063 // AlwaysAssert (dl.getHandle()); 00064 // </srcblock> 00065 // loads the executes library <src>bitflagsengine</src> and executes 00066 // the given register initialization function. 00067 // </example> 00068 00069 // <motivation> 00070 // dlopen is a standard UNIX system call, but some operating systems 00071 // do not support it or have different function names (notably Windows). 00072 // In this way use of dynamic libraries is centralized and can easily b 00073 // tailored as needed. 00074 // </motivation> 00075 00076 class DynLib 00077 { 00078 public: 00079 00080 // Load the dynamic library. It is tried with prefixes "lib" and <src>prefix</src> 00081 // and suffixes ".so" and ".dylib". 00082 // If not loaded successfully, the internal handle is NULL. 00083 // <br>If a non-empty funcName is given, that function is looked up and 00084 // executed. Its signature must be <src>void func()</src>. Note that the 00085 // function name should not be mangled, thus declared <src>extern "C"</src>. 00086 // An exception is thrown if the library is loaded successfully, but 00087 // <src>funcName</src> could not be found. 00088 // <br>If <src>closeOnDestruction=True</src>, the dynamic library is closed 00089 // on destruction of the DynLib object. 00090 DynLib (const std::string& library, 00091 const std::string& prefix=std::string(), 00092 const std::string& funcName=std::string(), 00093 bool closeOnDestruction=True); 00094 00095 // Load the dynamic library with the given name, prefix, and suffix. 00096 // If not loaded successfully, the internal handle is NULL. 00097 // <br>If <src>closeOnDestruction=True</src>, the dynamic library is closed 00098 // when the DynLib object is destructed. 00099 DynLib (const std::string& library, 00100 Bool closeOnDestruction, 00101 const std::string& prefix="lib", 00102 #ifdef __APPLE__ 00103 const std::string& suffix=".dylib"); 00104 #else 00105 const std::string& suffix=".so"); 00106 #endif 00107 00108 // Close the dynamic library if told so in the constructor. 00109 ~DynLib(); 00110 00111 // Get a pointer to a function in the dynamic library. 00112 // The pointer has to be casted with a reinterpret_cast to a function 00113 // pointer with the correct signature. When compiling with -pedantic the 00114 // compiler will give a warning for such a cast, because on some systems 00115 // (in particular some micro-controllers) a data pointer differs from a 00116 // function pointer. However, that problem cannot be solved. 00117 // For example: 00118 // <srcblock> 00119 // typedef Int MyFunc(Int, Int); 00120 // void* initfunc = DynLib::getFunc (mod, ("register_"+name).c_str()); 00121 // if (initFunc) { 00122 // MyFunc* func = reinterpret_cast<MyFunc*>(initfunc); 00123 // Int result = func(1,2); 00124 // } 00125 // </srcblock> 00126 // casts to a function returning Int and taking two Ints. 00127 // <br>A null pointer is returned if the function could not be found. 00128 void* getFunc (const std::string& funcName); 00129 00130 // Get the dynamic library handle. 00131 void* getHandle() const 00132 { return itsHandle; } 00133 00134 private: 00135 // Open (load)the dynamic library. 00136 void open (const std::string& name); 00137 00138 // Close (unload) the dynamic library (if opened). 00139 void close(); 00140 00141 //# Handle to dynamic library; note that the pointer is not owned, so the 00142 //# generated copy ctor and assignment are fine. 00143 void* itsHandle; 00144 Bool itsDoClose; 00145 }; 00146 00147 } //# NAMESPACE CASA - END 00148 00149 #endif