LibraryManager.h
Go to the documentation of this file.
1 #ifndef cetlib_LibraryManager_h
2 #define cetlib_LibraryManager_h
3 
4 #include "cetlib/hard_cast.h"
5 #include "cetlib/search_path.h"
6 #include "cetlib/shlib_utils.h"
7 
8 #include <cstring>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 namespace cet {
16  class LibraryManager;
17 }
18 
20 public:
21  // Create a LibraryManager that searches through a search path
22  // specified by search_path for dynamically loadable libraries
23  // having the given lib_type. Library names are expected to be of
24  // the form:
25  // libaa_bb_cc_xyz_<lib_type>.<ext>
26  // and where <ext> is provided automatically as appropriate for the
27  // platform.
29 
30  explicit LibraryManager(cet::search_path search_path,
31  std::string lib_type,
33 
34  // Use platform-dependent dynamic loader search path
35  explicit LibraryManager(std::string lib_type);
36  explicit LibraryManager(std::string lib_type, std::string pattern);
37 
38  // The d'tor does NOT unload libraries, because that is dangerous to
39  // do in C++. Use the compiler-generated destructor.
40  // ~LibraryManager();
41 
42  // Find and return a symbol named 'sym_name' in the library
43  // identified by 'libspec'. The library is dynamically loaded if
44  // necessary. If more than one library matching libspec is found, an
45  // exception is thrown. If the correct library cannot be found or
46  // loaded, an exception is thrown. If the symbol specified cannot be
47  // loaded, an exception is thrown unless the final argument to the
48  // function call is LibraryManager::nothrow, in which case the
49  // desired function pointer will be NULL.
50 
51  template <typename T>
52  T getSymbolByLibspec(std::string const& libspec,
53  std::string const& sym_name) const;
54  template <typename T>
55  void getSymbolByLibspec(std::string const& libspec,
56  std::string const& sym_name,
57  T& sym) const;
58 
59  template <typename T>
60  T getSymbolByPath(std::string const& lib_loc,
61  std::string const& sym_name) const;
62 
63  template <typename T>
64  void getSymbolByPath(std::string const& lib_loc,
65  std::string const& sym_name,
66  T& sym) const;
67 
68  // Versions which won't throw if they can't find the symbol.
69  static struct nothrow_t {
70  } nothrow;
71 
72  template <typename T>
73  T getSymbolByLibspec(std::string const& libspec,
74  std::string const& sym_name,
75  nothrow_t) const;
76  template <typename T>
77  void getSymbolByLibspec(std::string const& libspec,
78  std::string const& sym_name,
79  T& sym,
80  nothrow_t) const;
81  template <typename T>
82  T getSymbolByPath(std::string const& lib_loc,
83  std::string const& sym_name,
84  nothrow_t) const;
85  template <typename T>
86  void getSymbolByPath(std::string const& lib_loc,
87  std::string const& sym_name,
88  T& sym,
89  nothrow_t) const;
90 
91  // Get a list of loadable libraries (full paths). Returns the number
92  // of entries.
93  size_t getLoadableLibraries(std::vector<std::string>& list) const;
94  template <class OutIter>
95  size_t getLoadableLibraries(OutIter dest) const;
96 
97  // Get a list of already-loaded libraries (full paths). Returns the
98  // number of entries.
99  size_t getLoadedLibraries(std::vector<std::string>& list) const;
100  template <class OutIter>
101  size_t getLoadedLibraries(OutIter dest) const;
102 
103  // Get list of valid libspecs. Returns the number of entries.
104  size_t getValidLibspecs(std::vector<std::string>& list) const;
105  template <class OutIter>
106  size_t getValidLibspecs(OutIter dest) const;
107 
108  // Get pair of short and full libspecs corresponding to library full
109  // path.
110  std::pair<std::string, std::string> getSpecsByPath(
111  std::string const& lib_loc) const;
112 
113  // Load all libraries at once.
114  void loadAllLibraries() const;
115 
116  // Check whether libraries are loaded.
117  bool libraryIsLoaded(std::string const& path) const;
118  // Check whether library is loadable. Note this is *not* efficient
119  // and is only intended for diagnostic purposes. If it needs to be
120  // efficient the implementation will need to be improved.
121  bool libraryIsLoadable(std::string const& path) const;
122 
123  // This manager's library type.
125  libType() const
126  {
127  return lib_type_;
128  }
129 
130  // This managers library search pattern.
132  patternStem() const
133  {
134  return pattern_stem_;
135  }
136 
137 private:
138  // Internally-useful typedefs.
139  using lib_loc_map_t = std::map<std::string, std::string>;
140  using spec_trans_map_t = std::map<std::string, std::set<std::string>>;
141  using lib_ptr_map_t = std::map<std::string, void*>;
142  using good_spec_trans_map_t = std::map<std::string, std::string>;
143 
144  // Private helper functions.
145  static std::string dllExtPattern();
146 
147  void lib_loc_map_inserter(std::string const& path);
148  void spec_trans_map_inserter(lib_loc_map_t::value_type const& entry);
149  void good_spec_trans_map_inserter(spec_trans_map_t::value_type const& entry);
150  void* get_lib_ptr(std::string const& lib_loc) const;
151  void* getSymbolByLibspec_(std::string const& libspec,
152  std::string const& sym_name,
153  bool should_throw_on_dlsym = true) const;
154  void* getSymbolByPath_(std::string const& lib_loc,
155  std::string const& sym_name,
156  bool should_throw_on_dlsym = true) const;
157 
159  std::string const lib_type_; // eg _plugin.
160  std::string const pattern_stem_; // Library search pattern stem.
161  // Map of library filename -> full path.
163  // Map of spec -> full path.
165  // Map of only good translations.
167  // Cache of already-loaded libraries.
169 };
170 
171 inline std::string
173 {
174  static std::string const dllExtPatt{"\\" + shlib_suffix()};
175  return dllExtPatt;
176 }
177 
178 template <typename T>
179 inline T
181  std::string const& sym_name) const
182 {
183  return hard_cast<T>(getSymbolByLibspec_(libspec, sym_name));
184 }
185 
186 template <typename T>
187 inline void
189  std::string const& sym_name,
190  T& sym) const
191 {
192  hard_cast<T>(getSymbolByLibspec_(libspec, sym_name), sym);
193 }
194 
195 template <typename T>
196 inline T
198  std::string const& sym_name) const
199 {
200  return hard_cast<T>(getSymbolByPath_(lib_loc, sym_name));
201 }
202 
203 template <typename T>
204 inline void
206  std::string const& sym_name,
207  T& sym) const
208 {
209  hard_cast<T>(getSymbolByPath_(lib_loc, sym_name), sym);
210 }
211 
212 template <class OutIter>
213 size_t
215 {
216  size_t count{};
217  for (auto const& lib_loc : lib_loc_map_) {
218  *dest++ = lib_loc.second;
219  ++count;
220  }
221  return count;
222 }
223 
224 // Versions which won't throw on failure to obtain symbol.
225 template <typename T>
226 inline T
228  std::string const& sym_name,
229  nothrow_t) const
230 {
231  return hard_cast<T>(getSymbolByLibspec_(libspec, sym_name, false));
232 }
233 
234 template <typename T>
235 inline void
237  std::string const& sym_name,
238  T& sym,
239  nothrow_t) const
240 {
241  hard_cast<T>(getSymbolByLibspec_(libspec, sym_name, false), sym);
242 }
243 
244 template <typename T>
245 inline T
247  std::string const& sym_name,
248  nothrow_t) const
249 {
250  return hard_cast<T>(getSymbolByPath_(lib_loc, sym_name, false));
251 }
252 
253 template <typename T>
254 inline void
256  std::string const& sym_name,
257  T& sym,
258  nothrow_t) const
259 {
260  hard_cast<T>(getSymbolByPath_(lib_loc, sym_name, false), sym);
261 }
262 
263 template <class OutIter>
264 size_t
266 {
267  size_t count{};
268  for (auto const& lib_ptr : lib_ptr_map_) {
269  *dest++ = lib_ptr.first;
270  ++count;
271  }
272  return count;
273 }
274 
275 template <class OutIter>
276 size_t
278 {
279  size_t count{};
280  for (auto const& spec_trans : spec_trans_map_) {
281  *dest++ = spec_trans.first;
282  ++count;
283  }
284  return count;
285 }
286 
287 #endif /* cetlib_LibraryManager_h */
288 
289 // Local Variables:
290 // mode: c++
291 // End:
PTR_T hard_cast(void *src)
Definition: hard_cast.h:19
std::map< std::string, std::string > lib_loc_map_t
T getSymbolByPath(std::string const &lib_loc, std::string const &sym_name) const
QList< Entry > entry
void spec_trans_map_inserter(lib_loc_map_t::value_type const &entry)
size_t getLoadedLibraries(std::vector< std::string > &list) const
size_t getValidLibspecs(std::vector< std::string > &list) const
std::string string
Definition: nybbler.cc:12
void * getSymbolByLibspec_(std::string const &libspec, std::string const &sym_name, bool should_throw_on_dlsym=true) const
bool libraryIsLoadable(std::string const &path) const
void * getSymbolByPath_(std::string const &lib_loc, std::string const &sym_name, bool should_throw_on_dlsym=true) const
void lib_loc_map_inserter(std::string const &path)
LibraryManager(cet::search_path search_path, std::string lib_type)
cet::search_path const search_path_
std::string const pattern_stem_
std::map< std::string, void * > lib_ptr_map_t
std::string shlib_suffix()
static std::string dllExtPattern()
T getSymbolByLibspec(std::string const &libspec, std::string const &sym_name) const
std::string patternStem() const
std::map< std::string, std::string > good_spec_trans_map_t
spec_trans_map_t spec_trans_map_
std::pair< std::string, std::string > getSpecsByPath(std::string const &lib_loc) const
good_spec_trans_map_t good_spec_trans_map_
size_t getLoadableLibraries(std::vector< std::string > &list) const
static struct cet::LibraryManager::nothrow_t nothrow
void loadAllLibraries() const
void good_spec_trans_map_inserter(spec_trans_map_t::value_type const &entry)
bool libraryIsLoaded(std::string const &path) const
lib_ptr_map_t lib_ptr_map_
std::string pattern
Definition: regex_t.cc:35
std::map< std::string, std::set< std::string >> spec_trans_map_t
void * get_lib_ptr(std::string const &lib_loc) const
std::string const lib_type_
lib_loc_map_t lib_loc_map_
std::string libType() const