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
85class DynLib {
86 public:
87 // Load the dynamic library. It is tried with prefixes <src>prefix</src>
88 // and "lib" (in that order) and with suffix ".so" or ".dylib" (for Apple).
89 // No library version number is used.
90 // If not loaded successfully, an exception is thrown.
91 // <br>If a non-empty funcName is given, that function is looked up and
92 // executed for initialization purposes. Its signature must be
93 // <src>void func()</src>.
94 // Note that the function name should not be mangled, thus declared
95 // <src>extern "C"</src>.
96 // An exception is thrown if the library is loaded successfully, but
97 // <src>funcName</src> could not be found.
98 // <br>If <src>closeOnDestruction=True</src>, the dynamic library is
99 // closed on destruction of the DynLib object.
100 DynLib(const std::string& library, const std::string& prefix = std::string(),
101 const std::string& funcName = std::string(), bool closeOnDestruction = True);
102
103 // The same as above, but it is tried with and without the given version
104 // (in that order).
105 DynLib(const std::string& library, const std::string& prefix, const std::string& version,
106 const std::string& funcName, bool closeOnDestruction = True);
107
108 // Load the dynamic library with the given name, prefix, and suffix.
109 // If not loaded successfully, the internal handle is NULL.
110 // <br>If <src>closeOnDestruction=True</src>, the dynamic library is closed
111 // when the DynLib object is destructed.
112 DynLib(const std::string& library, Bool closeOnDestruction, const std::string& prefix = "lib",
113#ifdef __APPLE__
114 const std::string& suffix = ".dylib");
115#else
116 const std::string& suffix = ".so");
117#endif
118
119 // Close the dynamic library if told so in the constructor.
121
122 // Get a pointer to a function in the dynamic library.
123 // The pointer has to be casted with a reinterpret_cast to a function
124 // pointer with the correct signature. When compiling with -pedantic the
125 // compiler will give a warning for such a cast, because on some systems
126 // (in particular some micro-controllers) a data pointer differs from a
127 // function pointer. However, that problem cannot be solved.
128 // For example:
129 // <srcblock>
130 // typedef Int MyFunc(Int, Int);
131 // void* initfunc = DynLib::getFunc (mod, ("register_"+name).c_str());
132 // if (initFunc) {
133 // MyFunc* func = reinterpret_cast<MyFunc*>(initfunc);
134 // Int result = func(1,2);
135 // }
136 // </srcblock>
137 // casts to a function returning Int and taking two Ints.
138 // <br>A null pointer is returned if the function could not be found.
139 void* getFunc(const std::string& funcName);
140
141 // Get the dynamic library handle.
142 void* getHandle() const { return itsHandle; }
143
144 // Get the possible error.
145 const std::string& getError() const { return itsError; }
146
147 private:
148 // Try to open the library with some prefixes, suffixes and versions
149 // and to execute the initialization function.
150 // If successful, itsHandle is filled. Otherwise an exception is thrown.
151 void attach(const std::string& name, const std::string& prefix, const std::string& version,
152 const std::string& funcName);
153
154 // Try to open the library with some prefixes, suffixes and versions
155 // If successful, itsHandle is filled and the full library name is
156 // returned. Otherwise an empty name is returned.
157 std::string tryOpen(const std::string& name, const std::string& libdir, const std::string& prefix,
158 const std::string& version);
159
160 // Open (load) the dynamic library.
161 void open(const std::string& name);
162
163 // Close (unload) the dynamic library (if opened).
164 void close();
165
166 // Try if the library can be opened using CASACORE_LDPATH.
167 std::string tryCasacorePath(const std::string& library, const std::string& prefix,
168 const std::string& version);
169
170 // # Handle to dynamic library; note that the pointer is not owned, so the
171 // # generated copy ctor and assignment are fine.
174 std::string itsError;
175};
176
177} // namespace casacore
178
179#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:142
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:172
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:145
~DynLib()
Close the dynamic library if told so in the constructor.
std::string itsError
Definition DynLib.h:174
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
String name() const
Return the name of the field.
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
const Bool True
Definition aipstype.h:41