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: 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
35namespace 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.
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.
192 std::string itsError;
193 };
194
195} //# NAMESPACE CASACORE - END
196
197#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:153
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:190
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:157
~DynLib()
Close the dynamic library if told so in the constructor.
std::string itsError
Definition DynLib.h:192
this file contains all the compiler specific defines
Definition mainpage.dox:28
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:42
const Bool True
Definition aipstype.h:43