casacore
Loading...
Searching...
No Matches
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: casa-feedback@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#ifndef CASA_DYNLIB_H
27#define CASA_DYNLIB_H
28
29//# Includes
30#include <casacore/casa/aips.h>
31#include <string>
32
33namespace casacore { //# NAMESPACE CASACORE - BEGIN
34
35 // <summary>
36 // Class to handle loading of dynamic libraries
37 // </summary>
38 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
39 // </reviewed>
40
41 // <use visibility=export>
42
43 // <prerequisite>
44 // <li> Basic knowledge of the dlopen function family
45 // </prerequisite>
46
47 // <synopsis>
48 // This class makes it possible to load a dynamic library and execute an
49 // initialization function. Furthermore, one can get a pointer to any function
50 // in the dynamic library and close the library.
51 //
52 // The search path of the shared library is as follows:
53 // <ul>
54 // <li> If the environment library CASACORE_LDPATH is defined, it is tried to
55 // find the library using that path.
56 // <li> If not defined or not found, the system's (DY)LD_LIBRARY_PATH is used.
57 // <li> The library looked for has the name 'prefix'libname'suffix'.
58 // <br>As prefix first "lib" is used, thereafter the given one
59 // (e.g., "libcasa_").
60 // <br>As suffix first ".so" is used, thereafter ".dylib" (for OS-X).
61 // </ul>
62 //
63 // It is a wrapper around functions dlopen, dlsym, and dlclose.
64 // If dlopen and so are not supported on a platform, the class acts as if
65 // the shared library could not be found.
66 // </synopsis>
67
68 // <example>
69 // <srcblock>
70 // DynLib dl("derivedmscal", "libcasa_", "register_derivedmscal");
71 // AlwaysAssert (dl.getHandle());
72 // </srcblock>
73 // Using this
74 // loads the shared library <src>libcasa_derivedmscal.so</src> and
75 // executes the given register initialization function.
76 // </example>
77
78 // <motivation>
79 // dlopen is a standard UNIX system call, but some operating systems
80 // do not support it or have different function names (notably Windows).
81 // In this way use of dynamic libraries is centralized and can easily b
82 // tailored as needed.
83 // </motivation>
84
85 class DynLib
86 {
87 public:
88
89 // Load the dynamic library. It is tried with prefixes <src>prefix</src>
90 // and "lib" (in that order) and with suffix ".so" or ".dylib" (for Apple).
91 // No library version number is used.
92 // If not loaded successfully, an exception is thrown.
93 // <br>If a non-empty funcName is given, that function is looked up and
94 // executed for initialization purposes. Its signature must be
95 // <src>void func()</src>.
96 // Note that the function name should not be mangled, thus declared
97 // <src>extern "C"</src>.
98 // An exception is thrown if the library is loaded successfully, but
99 // <src>funcName</src> could not be found.
100 // <br>If <src>closeOnDestruction=True</src>, the dynamic library is
101 // closed on destruction of the DynLib object.
102 DynLib (const std::string& library,
103 const std::string& prefix=std::string(),
104 const std::string& funcName=std::string(),
105 bool closeOnDestruction=True);
106
107 // The same as above, but it is tried with and without the given version
108 // (in that order).
109 DynLib (const std::string& library,
110 const std::string& prefix,
111 const std::string& version,
112 const std::string& funcName,
113 bool closeOnDestruction=True);
114
115 // Load the dynamic library with the given name, prefix, and suffix.
116 // If not loaded successfully, the internal handle is NULL.
117 // <br>If <src>closeOnDestruction=True</src>, the dynamic library is closed
118 // when the DynLib object is destructed.
119 DynLib (const std::string& library,
120 Bool closeOnDestruction,
121 const std::string& prefix="lib",
122#ifdef __APPLE__
123 const std::string& suffix=".dylib");
124#else
125 const std::string& suffix=".so");
126#endif
127
128 // Close the dynamic library if told so in the constructor.
130
131 // Get a pointer to a function in the dynamic library.
132 // The pointer has to be casted with a reinterpret_cast to a function
133 // pointer with the correct signature. When compiling with -pedantic the
134 // compiler will give a warning for such a cast, because on some systems
135 // (in particular some micro-controllers) a data pointer differs from a
136 // function pointer. However, that problem cannot be solved.
137 // For example:
138 // <srcblock>
139 // typedef Int MyFunc(Int, Int);
140 // void* initfunc = DynLib::getFunc (mod, ("register_"+name).c_str());
141 // if (initFunc) {
142 // MyFunc* func = reinterpret_cast<MyFunc*>(initfunc);
143 // Int result = func(1,2);
144 // }
145 // </srcblock>
146 // casts to a function returning Int and taking two Ints.
147 // <br>A null pointer is returned if the function could not be found.
148 void* getFunc (const std::string& funcName);
149
150 // Get the dynamic library handle.
151 void* getHandle() const
152 { return itsHandle; }
153
154 // Get the possible error.
155 const std::string& getError() const
156 { return itsError; }
157
158 private:
159 // Try to open the library with some prefixes, suffixes and versions
160 // and to execute the initialization function.
161 // If successful, itsHandle is filled. Otherwise an exception is thrown.
162 void attach (const std::string& name,
163 const std::string& prefix,
164 const std::string& version,
165 const std::string& funcName);
166
167 // Try to open the library with some prefixes, suffixes and versions
168 // If successful, itsHandle is filled and the full library name is
169 // returned. Otherwise an empty name is returned.
170 std::string tryOpen (const std::string& name,
171 const std::string& libdir,
172 const std::string& prefix,
173 const std::string& version);
174
175 // Open (load) the dynamic library.
176 void open (const std::string& name);
177
178 // Close (unload) the dynamic library (if opened).
179 void close();
180
181 // Try if the library can be opened using CASACORE_LDPATH.
182 std::string tryCasacorePath (const std::string& library,
183 const std::string& prefix,
184 const std::string& version);
185
186 //# Handle to dynamic library; note that the pointer is not owned, so the
187 //# generated copy ctor and assignment are fine.
190 std::string itsError;
191 };
192
193} //# NAMESPACE CASACORE - END
194
195#endif
void open(const std::string &name)
Open (load) the dynamic library.
void * getFunc(const std::string &funcName)
Get a pointer to a function in the dynamic library.
DynLib(const std::string &library, const std::string &prefix, const std::string &version, const std::string &funcName, bool closeOnDestruction=True)
The same as above, but it is tried with and without the given version (in that order).
DynLib(const std::string &library, Bool closeOnDestruction, const std::string &prefix="lib", const std::string &suffix=".so")
Load the dynamic library with the given name, prefix, and suffix.
void * getHandle() const
Get the dynamic library handle.
Definition DynLib.h:151
void close()
Close (unload) the dynamic library (if opened).
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.
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 ...
void * itsHandle
Definition DynLib.h:188
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...
DynLib(const std::string &library, const std::string &prefix=std::string(), const std::string &funcName=std::string(), bool closeOnDestruction=True)
Load the dynamic library.
const std::string & getError() const
Get the possible error.
Definition DynLib.h:155
~DynLib()
Close the dynamic library if told so in the constructor.
std::string itsError
Definition DynLib.h:190
this file contains all the compiler specific defines
Definition mainpage.dox:28
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
const Bool True
Definition aipstype.h:41