casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DynLib.h
Go to the documentation of this file.
1 //# DynLib.h: Class to handle loadig of dynamic libraries
2 //# Copyright (C) 2009
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef CASA_DYNLIB_H
29 #define CASA_DYNLIB_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
33 #include <string>
34 
35 namespace casacore { //# NAMESPACE CASACORE - BEGIN
36 
37  // <summary>
38  // Class to handle loading of dynamic libraries
39  // </summary>
40  // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
41  // </reviewed>
42 
43  // <use visibility=export>
44 
45  // <prerequisite>
46  // <li> Basic knowledge of the dlopen function family
47  // </prerequisite>
48 
49  // <synopsis>
50  // This class makes it possible to load a dynamic library and execute an
51  // initialization function. Furthermore, one can get a pointer to any function
52  // in the dynamic library and close the library.
53  //
54  // The search path of the shared library is as follows:
55  // <ul>
56  // <li> If the environment library CASACORE_LDPATH is defined, it is tried to
57  // find the library using that path.
58  // <li> If not defined or not found, the system's (DY)LD_LIBRARY_PATH is used.
59  // <li> The library looked for has the name 'prefix'libname'suffix'.
60  // <br>As prefix first "lib" is used, thereafter the given one
61  // (e.g., "libcasa_").
62  // <br>As suffix first ".so" is used, thereafter ".dylib" (for OS-X).
63  // </ul>
64  //
65  // It is a wrapper around functions dlopen, dlsym, and dlclose.
66  // If dlopen and so are not supported on a platform, the class acts as if
67  // the shared library could not be found.
68  // </synopsis>
69 
70  // <example>
71  // <srcblock>
72  // DynLib dl("derivedmscal", "libcasa_", "register_derivedmscal");
73  // AlwaysAssert (dl.getHandle());
74  // </srcblock>
75  // Using this
76  // loads the shared library <src>libcasa_derivedmscal.so</src> and
77  // executes the given register initialization function.
78  // </example>
79 
80  // <motivation>
81  // dlopen is a standard UNIX system call, but some operating systems
82  // do not support it or have different function names (notably Windows).
83  // In this way use of dynamic libraries is centralized and can easily b
84  // tailored as needed.
85  // </motivation>
86 
87  class DynLib
88  {
89  public:
90 
91  // Load the dynamic library. It is tried with prefixes <src>prefix</src>
92  // and "lib" (in that order) and with suffix ".so" or ".dylib" (for Apple).
93  // No library version number is used.
94  // If not loaded successfully, an exception is thrown.
95  // <br>If a non-empty funcName is given, that function is looked up and
96  // executed for initialization purposes. Its signature must be
97  // <src>void func()</src>.
98  // Note that the function name should not be mangled, thus declared
99  // <src>extern "C"</src>.
100  // An exception is thrown if the library is loaded successfully, but
101  // <src>funcName</src> could not be found.
102  // <br>If <src>closeOnDestruction=True</src>, the dynamic library is
103  // closed on destruction of the DynLib object.
104  DynLib (const std::string& library,
105  const std::string& prefix=std::string(),
106  const std::string& funcName=std::string(),
107  bool closeOnDestruction=True);
108 
109  // The same as above, but it is tried with and without the given version
110  // (in that order).
111  DynLib (const std::string& library,
112  const std::string& prefix,
113  const std::string& version,
114  const std::string& funcName,
115  bool closeOnDestruction=True);
116 
117  // Load the dynamic library with the given name, prefix, and suffix.
118  // If not loaded successfully, the internal handle is NULL.
119  // <br>If <src>closeOnDestruction=True</src>, the dynamic library is closed
120  // when the DynLib object is destructed.
121  DynLib (const std::string& library,
122  Bool closeOnDestruction,
123  const std::string& prefix="lib",
124 #ifdef __APPLE__
125  const std::string& suffix=".dylib");
126 #else
127  const std::string& suffix=".so");
128 #endif
129 
130  // Close the dynamic library if told so in the constructor.
131  ~DynLib();
132 
133  // Get a pointer to a function in the dynamic library.
134  // The pointer has to be casted with a reinterpret_cast to a function
135  // pointer with the correct signature. When compiling with -pedantic the
136  // compiler will give a warning for such a cast, because on some systems
137  // (in particular some micro-controllers) a data pointer differs from a
138  // function pointer. However, that problem cannot be solved.
139  // For example:
140  // <srcblock>
141  // typedef Int MyFunc(Int, Int);
142  // void* initfunc = DynLib::getFunc (mod, ("register_"+name).c_str());
143  // if (initFunc) {
144  // MyFunc* func = reinterpret_cast<MyFunc*>(initfunc);
145  // Int result = func(1,2);
146  // }
147  // </srcblock>
148  // casts to a function returning Int and taking two Ints.
149  // <br>A null pointer is returned if the function could not be found.
150  void* getFunc (const std::string& funcName);
151 
152  // Get the dynamic library handle.
153  void* getHandle() const
154  { return itsHandle; }
155 
156  // Get the possible error.
157  const std::string& getError() const
158  { return itsError; }
159 
160  private:
161  // Try to open the library with some prefixes, suffixes and versions
162  // and to execute the initialization function.
163  // If successful, itsHandle is filled. Otherwise an exception is thrown.
164  void attach (const std::string& name,
165  const std::string& prefix,
166  const std::string& version,
167  const std::string& funcName);
168 
169  // Try to open the library with some prefixes, suffixes and versions
170  // If successful, itsHandle is filled and the full library name is
171  // returned. Otherwise an empty name is returned.
172  std::string tryOpen (const std::string& name,
173  const std::string& libdir,
174  const std::string& prefix,
175  const std::string& version);
176 
177  // Open (load) the dynamic library.
178  void open (const std::string& name);
179 
180  // Close (unload) the dynamic library (if opened).
181  void close();
182 
183  // Try if the library can be opened using CASACORE_LDPATH.
184  std::string tryCasacorePath (const std::string& library,
185  const std::string& prefix,
186  const std::string& version);
187 
188  //# Handle to dynamic library; note that the pointer is not owned, so the
189  //# generated copy ctor and assignment are fine.
190  void* itsHandle;
192  std::string itsError;
193  };
194 
195 } //# NAMESPACE CASACORE - END
196 
197 #endif
void * itsHandle
Definition: DynLib.h:190
void open(const std::string &name)
Open (load) the dynamic library.
std::string tryOpen(const std::string &name, const std::string &libdir, const std::string &prefix, const std::string &version)
Try to open the library with some prefixes, suffixes and versions If successful, itsHandle is filled ...
DynLib(const std::string &library, const std::string &prefix=std::string(), const std::string &funcName=std::string(), bool closeOnDestruction=True)
Load the dynamic library.
void attach(const std::string &name, const std::string &prefix, const std::string &version, const std::string &funcName)
Try to open the library with some prefixes, suffixes and versions and to execute the initialization f...
ABSTRACT CLASSES Abstract class for colors Any implementation of color should be able to provide a hexadecimal form of the if a human readable name(i.e."black").In many places throughout the plotter
const std::string & getError() const
Get the possible error.
Definition: DynLib.h:157
Class to handle loading of dynamic libraries.
Definition: DynLib.h:87
void * getFunc(const std::string &funcName)
Get a pointer to a function in the dynamic library.
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
void close()
Close (unload) the dynamic library (if opened).
std::string itsError
Definition: DynLib.h:192
void * getHandle() const
Get the dynamic library handle.
Definition: DynLib.h:153
std::string tryCasacorePath(const std::string &library, const std::string &prefix, const std::string &version)
Try if the library can be opened using CASACORE_LDPATH.
Bool itsDoClose
Definition: DynLib.h:191
const Bool True
Definition: aipstype.h:43
~DynLib()
Close the dynamic library if told so in the constructor.
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42