]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright 2014 Renato Tegon Forti, Antony Polukhin. |
1e59de90 | 2 | // Copyright Antony Polukhin, 2015-2022. |
7c673cae FG |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt | |
6 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifndef BOOST_DLL_SHARED_LIBRARY_HPP | |
9 | #define BOOST_DLL_SHARED_LIBRARY_HPP | |
10 | ||
11 | /// \file boost/dll/shared_library.hpp | |
12 | /// \brief Contains the boost::dll::shared_library class, core class for all the | |
13 | /// DLL/DSO operations. | |
14 | ||
92f5a8d4 | 15 | #include <boost/dll/config.hpp> |
7c673cae | 16 | #include <boost/predef/os.h> |
11fdf7f2 TL |
17 | #include <boost/core/enable_if.hpp> |
18 | #include <boost/core/explicit_operator_bool.hpp> | |
7c673cae | 19 | #include <boost/type_traits/is_member_pointer.hpp> |
7c673cae FG |
20 | #include <boost/dll/detail/system_error.hpp> |
21 | #include <boost/dll/detail/aggressive_ptr_cast.hpp> | |
22 | ||
23 | #if BOOST_OS_WINDOWS | |
24 | # include <boost/dll/detail/windows/shared_library_impl.hpp> | |
25 | #else | |
26 | # include <boost/dll/detail/posix/shared_library_impl.hpp> | |
27 | #endif | |
28 | ||
29 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
30 | # pragma once | |
31 | #endif | |
32 | ||
33 | namespace boost { namespace dll { | |
34 | ||
35 | /*! | |
36 | * \brief This class can be used to load a | |
37 | * Dynamic link libraries (DLL's) or Shared Libraries, also know | |
38 | * as dynamic shared objects (DSO's) and get their exported | |
39 | * symbols (functions and variables). | |
40 | * | |
41 | * shared_library instances share reference count to an actual loaded DLL/DSO, so it | |
42 | * is safe and memory efficient to have multiple instances of shared_library referencing the same DLL/DSO | |
43 | * even if those instances were loaded using different paths (relative + absolute) referencing the same object. | |
44 | * | |
45 | * On Linux/POSIX link with library "dl". "-fvisibility=hidden" flag is also recommended for use on Linux/POSIX. | |
46 | */ | |
47 | class shared_library | |
48 | /// @cond | |
49 | : private boost::dll::detail::shared_library_impl | |
50 | /// @endcond | |
51 | { | |
52 | typedef boost::dll::detail::shared_library_impl base_t; | |
53 | BOOST_COPYABLE_AND_MOVABLE(shared_library) | |
54 | ||
55 | public: | |
56 | #ifdef BOOST_DLL_DOXYGEN | |
57 | typedef platform_specific native_handle_t; | |
92f5a8d4 | 58 | #else |
7c673cae FG |
59 | typedef shared_library_impl::native_handle_t native_handle_t; |
60 | #endif | |
61 | ||
62 | /*! | |
63 | * Creates in anstance that does not reference any DLL/DSO. | |
64 | * | |
65 | * \post this->is_loaded() returns false. | |
66 | * \throw Nothing. | |
67 | */ | |
68 | shared_library() BOOST_NOEXCEPT {} | |
69 | ||
70 | /*! | |
71 | * Copy constructor that increments the reference count of an underlying shared library. | |
72 | * Same as calling constructor with `lib.location()` parameter. | |
73 | * | |
74 | * \param lib A library to copy. | |
75 | * \post lib == *this | |
92f5a8d4 | 76 | * \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory. |
7c673cae FG |
77 | */ |
78 | shared_library(const shared_library& lib) | |
79 | : base_t() | |
80 | { | |
81 | assign(lib); | |
82 | } | |
83 | ||
84 | /*! | |
85 | * Copy constructor that increments the reference count of an underlying shared library. | |
86 | * Same as calling constructor with `lib.location(), ec` parameters. | |
87 | * | |
88 | * \param lib A shared library to copy. | |
89 | * \param ec Variable that will be set to the result of the operation. | |
90 | * \post lib == *this | |
91 | * \throw std::bad_alloc in case of insufficient memory. | |
92 | */ | |
92f5a8d4 | 93 | shared_library(const shared_library& lib, boost::dll::fs::error_code& ec) |
7c673cae FG |
94 | : base_t() |
95 | { | |
96 | assign(lib, ec); | |
97 | } | |
98 | ||
99 | /*! | |
100 | * Move constructor. Does not invalidate existing symbols and functions loaded from lib. | |
101 | * | |
102 | * \param lib A shared library to move from. | |
103 | * \post lib.is_loaded() returns false, this->is_loaded() return true. | |
104 | * \throw Nothing. | |
105 | */ | |
106 | shared_library(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT | |
107 | : base_t(boost::move(static_cast<base_t&>(lib))) | |
108 | {} | |
109 | ||
110 | /*! | |
111 | * Loads a library by specified path with a specified mode. | |
112 | * | |
113 | * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, | |
92f5a8d4 | 114 | * const wchar_t* or \forcedlinkfs{path}. |
7c673cae | 115 | * \param mode A mode that will be used on library load. |
92f5a8d4 | 116 | * \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory. |
7c673cae | 117 | */ |
92f5a8d4 | 118 | explicit shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) { |
7c673cae FG |
119 | shared_library::load(lib_path, mode); |
120 | } | |
121 | ||
122 | /*! | |
123 | * Loads a library by specified path with a specified mode. | |
124 | * | |
125 | * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, | |
92f5a8d4 | 126 | * const wchar_t* or \forcedlinkfs{path}. |
7c673cae FG |
127 | * \param mode A mode that will be used on library load. |
128 | * \param ec Variable that will be set to the result of the operation. | |
129 | * \throw std::bad_alloc in case of insufficient memory. | |
130 | */ | |
92f5a8d4 | 131 | shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) { |
7c673cae FG |
132 | shared_library::load(lib_path, mode, ec); |
133 | } | |
134 | ||
92f5a8d4 TL |
135 | //! \overload shared_library(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) |
136 | shared_library(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) { | |
7c673cae FG |
137 | shared_library::load(lib_path, mode, ec); |
138 | } | |
139 | ||
140 | /*! | |
141 | * Assignment operator. If this->is_loaded() then calls this->unload(). Does not invalidate existing symbols and functions loaded from lib. | |
142 | * | |
143 | * \param lib A shared library to assign from. | |
144 | * \post lib == *this | |
92f5a8d4 | 145 | * \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory. |
7c673cae FG |
146 | */ |
147 | shared_library& operator=(BOOST_COPY_ASSIGN_REF(shared_library) lib) { | |
92f5a8d4 | 148 | boost::dll::fs::error_code ec; |
7c673cae FG |
149 | assign(lib, ec); |
150 | if (ec) { | |
151 | boost::dll::detail::report_error(ec, "boost::dll::shared_library::operator= failed"); | |
152 | } | |
153 | ||
154 | return *this; | |
155 | } | |
156 | ||
157 | /*! | |
158 | * Move assignment operator. If this->is_loaded() then calls this->unload(). Does not invalidate existing symbols and functions loaded from lib. | |
159 | * | |
160 | * \param lib A library to move from. | |
161 | * \post lib.is_loaded() returns false. | |
162 | * \throw Nothing. | |
163 | */ | |
164 | shared_library& operator=(BOOST_RV_REF(shared_library) lib) BOOST_NOEXCEPT { | |
165 | if (lib.native() != native()) { | |
166 | swap(lib); | |
167 | } | |
168 | ||
169 | return *this; | |
170 | } | |
171 | ||
172 | /*! | |
173 | * Destroys the object by calling `unload()`. If library was loaded multiple times | |
174 | * by different instances, the actual DLL/DSO won't be unloaded until | |
175 | * there is at least one instance that references the DLL/DSO. | |
176 | * | |
177 | * \throw Nothing. | |
178 | */ | |
179 | ~shared_library() BOOST_NOEXCEPT {} | |
180 | ||
181 | /*! | |
182 | * Makes *this share the same shared object as lib. If *this is loaded, then unloads it. | |
183 | * | |
184 | * \post lib.location() == this->location(), lib == *this | |
185 | * \param lib A library to copy. | |
186 | * \param ec Variable that will be set to the result of the operation. | |
187 | * \throw std::bad_alloc in case of insufficient memory. | |
188 | */ | |
92f5a8d4 | 189 | shared_library& assign(const shared_library& lib, boost::dll::fs::error_code& ec) { |
7c673cae FG |
190 | ec.clear(); |
191 | ||
192 | if (native() == lib.native()) { | |
193 | return *this; | |
194 | } | |
195 | ||
196 | if (!lib) { | |
197 | unload(); | |
198 | return *this; | |
199 | } | |
200 | ||
92f5a8d4 | 201 | boost::dll::fs::path loc = lib.location(ec); |
7c673cae FG |
202 | if (ec) { |
203 | return *this; | |
204 | } | |
205 | ||
206 | shared_library copy(loc, ec); | |
207 | if (ec) { | |
208 | return *this; | |
209 | } | |
210 | ||
211 | swap(copy); | |
212 | return *this; | |
213 | } | |
214 | ||
215 | /*! | |
216 | * Makes *this share the same shared object as lib. If *this is loaded, then unloads it. | |
217 | * | |
218 | * \param lib A library instance to assign from. | |
219 | * \post lib.location() == this->location() | |
92f5a8d4 | 220 | * \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory. |
7c673cae FG |
221 | */ |
222 | shared_library& assign(const shared_library& lib) { | |
92f5a8d4 | 223 | boost::dll::fs::error_code ec; |
7c673cae FG |
224 | assign(lib, ec); |
225 | if (ec) { | |
226 | boost::dll::detail::report_error(ec, "boost::dll::shared_library::assign() failed"); | |
227 | } | |
228 | ||
229 | return *this; | |
230 | } | |
231 | ||
232 | /*! | |
233 | * Loads a library by specified path with a specified mode. | |
234 | * | |
235 | * Note that if some library is already loaded in this instance, load will | |
236 | * call unload() and then load the new provided library. | |
237 | * | |
238 | * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, | |
92f5a8d4 | 239 | * const wchar_t* or \forcedlinkfs{path}. |
7c673cae | 240 | * \param mode A mode that will be used on library load. |
92f5a8d4 | 241 | * \throw \forcedlinkfs{system_error}, std::bad_alloc in case of insufficient memory. |
7c673cae FG |
242 | * |
243 | */ | |
92f5a8d4 TL |
244 | void load(const boost::dll::fs::path& lib_path, load_mode::type mode = load_mode::default_mode) { |
245 | boost::dll::fs::error_code ec; | |
7c673cae FG |
246 | |
247 | base_t::load(lib_path, mode, ec); | |
248 | ||
249 | if (ec) { | |
250 | boost::dll::detail::report_error(ec, "boost::dll::shared_library::load() failed"); | |
251 | } | |
252 | } | |
253 | ||
254 | /*! | |
255 | * Loads a library by specified path with a specified mode. | |
256 | * | |
257 | * Note that if some library is already loaded in this instance, load will | |
258 | * call unload() and then load the new provided library. | |
259 | * | |
260 | * \param lib_path Library file name. Can handle std::string, const char*, std::wstring, | |
92f5a8d4 | 261 | * const wchar_t* or \forcedlinkfs{path}. |
7c673cae FG |
262 | * \param ec Variable that will be set to the result of the operation. |
263 | * \param mode A mode that will be used on library load. | |
264 | * \throw std::bad_alloc in case of insufficient memory. | |
265 | */ | |
92f5a8d4 | 266 | void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) { |
7c673cae FG |
267 | ec.clear(); |
268 | base_t::load(lib_path, mode, ec); | |
269 | } | |
270 | ||
92f5a8d4 TL |
271 | //! \overload void load(const boost::dll::fs::path& lib_path, boost::dll::fs::error_code& ec, load_mode::type mode = load_mode::default_mode) |
272 | void load(const boost::dll::fs::path& lib_path, load_mode::type mode, boost::dll::fs::error_code& ec) { | |
7c673cae FG |
273 | ec.clear(); |
274 | base_t::load(lib_path, mode, ec); | |
275 | } | |
276 | ||
277 | /*! | |
278 | * Unloads a shared library. If library was loaded multiple times | |
279 | * by different instances, the actual DLL/DSO won't be unloaded until | |
280 | * there is at least one instance that references the DLL/DSO. | |
281 | * | |
282 | * \post this->is_loaded() returns false. | |
283 | * \throw Nothing. | |
284 | */ | |
285 | void unload() BOOST_NOEXCEPT { | |
286 | base_t::unload(); | |
287 | } | |
288 | ||
289 | /*! | |
290 | * Check if an library is loaded. | |
291 | * | |
292 | * \return true if a library has been loaded. | |
293 | * \throw Nothing. | |
294 | */ | |
295 | bool is_loaded() const BOOST_NOEXCEPT { | |
296 | return base_t::is_loaded(); | |
297 | } | |
298 | ||
299 | /*! | |
300 | * Check if an library is not loaded. | |
301 | * | |
302 | * \return true if a library has not been loaded. | |
303 | * \throw Nothing. | |
304 | */ | |
305 | bool operator!() const BOOST_NOEXCEPT { | |
306 | return !is_loaded(); | |
307 | } | |
308 | ||
309 | /*! | |
310 | * Check if an library is loaded. | |
311 | * | |
312 | * \return true if a library has been loaded. | |
313 | * \throw Nothing. | |
314 | */ | |
315 | BOOST_EXPLICIT_OPERATOR_BOOL() | |
316 | ||
317 | /*! | |
318 | * Search for a given symbol on loaded library. Works for all symbols, including alias names. | |
319 | * | |
320 | * \param symbol_name Null-terminated symbol name. Can handle std::string, char*, const char*. | |
321 | * \return `true` if the loaded library contains a symbol with a given name. | |
322 | * \throw Nothing. | |
323 | */ | |
324 | bool has(const char* symbol_name) const BOOST_NOEXCEPT { | |
92f5a8d4 | 325 | boost::dll::fs::error_code ec; |
7c673cae FG |
326 | return is_loaded() && !!base_t::symbol_addr(symbol_name, ec) && !ec; |
327 | } | |
328 | ||
329 | //! \overload bool has(const char* symbol_name) const | |
330 | bool has(const std::string& symbol_name) const BOOST_NOEXCEPT { | |
331 | return has(symbol_name.c_str()); | |
332 | } | |
333 | ||
334 | /*! | |
335 | * Returns reference to the symbol (function or variable) with the given name from the loaded library. | |
336 | * This call will always succeed and throw nothing if call to `has(const char* )` | |
337 | * member function with the same symbol name returned `true`. | |
338 | * | |
339 | * \b Example: | |
340 | * \code | |
341 | * int& i0 = lib.get<int>("integer_name"); | |
342 | * int& i1 = *lib.get<int*>("integer_alias_name"); | |
343 | * \endcode | |
344 | * | |
345 | * \tparam T Type of the symbol that we are going to import. Must be explicitly specified. | |
346 | * \param symbol_name Null-terminated symbol name. Can handle std::string, char*, const char*. | |
347 | * \return Reference to the symbol. | |
92f5a8d4 | 348 | * \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded. |
7c673cae FG |
349 | */ |
350 | template <typename T> | |
351 | inline typename boost::enable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T>::type get(const std::string& symbol_name) const { | |
352 | return get<T>(symbol_name.c_str()); | |
353 | } | |
354 | ||
355 | //! \overload T& get(const std::string& symbol_name) const | |
356 | template <typename T> | |
357 | inline typename boost::disable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T&>::type get(const std::string& symbol_name) const { | |
358 | return get<T>(symbol_name.c_str()); | |
359 | } | |
360 | ||
361 | //! \overload T& get(const std::string& symbol_name) const | |
362 | template <typename T> | |
363 | inline typename boost::enable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T>::type get(const char* symbol_name) const { | |
364 | return boost::dll::detail::aggressive_ptr_cast<T>( | |
365 | get_void(symbol_name) | |
366 | ); | |
367 | } | |
368 | ||
369 | //! \overload T& get(const std::string& symbol_name) const | |
370 | template <typename T> | |
371 | inline typename boost::disable_if_c<boost::is_member_pointer<T>::value || boost::is_reference<T>::value, T&>::type get(const char* symbol_name) const { | |
372 | return *boost::dll::detail::aggressive_ptr_cast<T*>( | |
373 | get_void(symbol_name) | |
374 | ); | |
375 | } | |
376 | ||
377 | /*! | |
378 | * Returns a symbol (function or variable) from a shared library by alias name of the symbol. | |
379 | * | |
380 | * \b Example: | |
381 | * \code | |
382 | * int& i = lib.get_alias<int>("integer_alias_name"); | |
383 | * \endcode | |
384 | * | |
385 | * \tparam T Type of the symbol that we are going to import. Must be explicitly specified.. | |
386 | * \param alias_name Null-terminated alias symbol name. Can handle std::string, char*, const char*. | |
92f5a8d4 | 387 | * \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded. |
7c673cae FG |
388 | */ |
389 | template <typename T> | |
390 | inline T& get_alias(const char* alias_name) const { | |
391 | return *get<T*>(alias_name); | |
392 | } | |
393 | ||
394 | //! \overload T& get_alias(const char* alias_name) const | |
395 | template <typename T> | |
396 | inline T& get_alias(const std::string& alias_name) const { | |
397 | return *get<T*>(alias_name.c_str()); | |
398 | } | |
399 | ||
400 | private: | |
401 | /// @cond | |
402 | // get_void is required to reduce binary size: it does not depend on a template | |
403 | // parameter and will be instantiated only once. | |
404 | void* get_void(const char* sb) const { | |
92f5a8d4 | 405 | boost::dll::fs::error_code ec; |
7c673cae FG |
406 | |
407 | if (!is_loaded()) { | |
92f5a8d4 TL |
408 | ec = boost::dll::fs::make_error_code( |
409 | boost::dll::fs::errc::bad_file_descriptor | |
7c673cae FG |
410 | ); |
411 | ||
412 | // report_error() calls dlsym, do not use it here! | |
413 | boost::throw_exception( | |
92f5a8d4 | 414 | boost::dll::fs::system_error( |
7c673cae FG |
415 | ec, "boost::dll::shared_library::get() failed: no library was loaded" |
416 | ) | |
417 | ); | |
418 | } | |
419 | ||
420 | void* const ret = base_t::symbol_addr(sb, ec); | |
421 | if (ec || !ret) { | |
422 | boost::dll::detail::report_error(ec, "boost::dll::shared_library::get() failed"); | |
423 | } | |
424 | ||
425 | return ret; | |
426 | } | |
427 | /// @endcond | |
428 | ||
429 | public: | |
430 | ||
431 | /*! | |
432 | * Returns the native handler of the loaded library. | |
433 | * | |
434 | * \return Platform-specific handle. | |
435 | */ | |
436 | native_handle_t native() const BOOST_NOEXCEPT { | |
437 | return base_t::native(); | |
438 | } | |
439 | ||
440 | /*! | |
441 | * Returns full path and name of this shared object. | |
442 | * | |
443 | * \b Example: | |
444 | * \code | |
445 | * shared_library lib("test_lib.dll"); | |
446 | * filesystem::path full_path = lib.location(); // C:\Windows\System32\test_lib.dll | |
447 | * \endcode | |
448 | * | |
449 | * \return Full path to the shared library. | |
92f5a8d4 | 450 | * \throw \forcedlinkfs{system_error}, std::bad_alloc. |
7c673cae | 451 | */ |
92f5a8d4 TL |
452 | boost::dll::fs::path location() const { |
453 | boost::dll::fs::error_code ec; | |
7c673cae | 454 | if (!is_loaded()) { |
92f5a8d4 TL |
455 | ec = boost::dll::fs::make_error_code( |
456 | boost::dll::fs::errc::bad_file_descriptor | |
7c673cae FG |
457 | ); |
458 | ||
459 | boost::throw_exception( | |
92f5a8d4 | 460 | boost::dll::fs::system_error( |
7c673cae FG |
461 | ec, "boost::dll::shared_library::location() failed (no library was loaded)" |
462 | ) | |
463 | ); | |
464 | } | |
465 | ||
92f5a8d4 | 466 | boost::dll::fs::path full_path = base_t::full_module_path(ec); |
7c673cae FG |
467 | |
468 | if (ec) { | |
469 | boost::dll::detail::report_error(ec, "boost::dll::shared_library::location() failed"); | |
470 | } | |
471 | ||
472 | return full_path; | |
473 | } | |
474 | ||
475 | /*! | |
476 | * Returns full path and name of shared module. | |
477 | * | |
478 | * \b Example: | |
479 | * \code | |
480 | * shared_library lib("test_lib.dll"); | |
481 | * filesystem::path full_path = lib.location(); // C:\Windows\System32\test_lib.dll | |
482 | * \endcode | |
483 | * | |
484 | * \param ec Variable that will be set to the result of the operation. | |
485 | * \return Full path to the shared library. | |
486 | * \throw std::bad_alloc. | |
487 | */ | |
92f5a8d4 | 488 | boost::dll::fs::path location(boost::dll::fs::error_code& ec) const { |
7c673cae | 489 | if (!is_loaded()) { |
92f5a8d4 TL |
490 | ec = boost::dll::fs::make_error_code( |
491 | boost::dll::fs::errc::bad_file_descriptor | |
7c673cae FG |
492 | ); |
493 | ||
92f5a8d4 | 494 | return boost::dll::fs::path(); |
7c673cae FG |
495 | } |
496 | ||
497 | ec.clear(); | |
498 | return base_t::full_module_path(ec); | |
499 | } | |
500 | ||
501 | /*! | |
502 | * Returns suffix of shared module: | |
503 | * in a call to load() or the constructor/load. | |
504 | * | |
505 | * \return The suffix od shared module: ".dll" (Windows), ".so" (Unix/Linux/BSD), ".dylib" (MacOS/IOS) | |
506 | */ | |
92f5a8d4 | 507 | static boost::dll::fs::path suffix() { |
7c673cae FG |
508 | return base_t::suffix(); |
509 | } | |
510 | ||
92f5a8d4 TL |
511 | /*! |
512 | * Returns the decorated path to a shared module name, i.e. with needed prefix/suffix added. | |
513 | * | |
514 | * \b Recommendations: Use `load` with `load_mode::append_decorations` instead of constructing the decorated path via `decorate()` and loading by it. | |
515 | * | |
516 | * For instance, for a path like "path/to/boost" it returns : | |
517 | * - path/to/libboost.so on posix platforms | |
518 | * - path/to/libboost.dylib on OSX | |
519 | * - path/to/boost.dll on Windows | |
520 | * | |
521 | * Method handles both relative and absolute paths. | |
522 | * | |
523 | * - Windows note: `decorate()` does not prepend "lib" to the decorated path. Use `load` with `load_mode::append_decorations` for MinGW compatibility purpose. | |
524 | * - Posix note: if the initial module name is already prepended with lib, only the suffix() is appended to the path | |
525 | * | |
526 | * \param sl the module name and path to decorate - for instance : /usr/lib/boost | |
527 | * | |
528 | * \return The decorated unportable path that may not exists in the filesystem or could be wrong due to platform specifics. | |
529 | */ | |
530 | static boost::dll::fs::path decorate(const boost::dll::fs::path& sl) { | |
531 | return base_t::decorate(sl); | |
532 | } | |
533 | ||
7c673cae FG |
534 | /*! |
535 | * Swaps two libraries. Does not invalidate existing symbols and functions loaded from libraries. | |
536 | * | |
537 | * \param rhs Library to swap with. | |
538 | * \throw Nothing. | |
539 | */ | |
540 | void swap(shared_library& rhs) BOOST_NOEXCEPT { | |
541 | base_t::swap(rhs); | |
542 | } | |
543 | }; | |
544 | ||
545 | ||
546 | ||
547 | /// Very fast equality check that compares the actual DLL/DSO objects. Throws nothing. | |
548 | inline bool operator==(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT { | |
549 | return lhs.native() == rhs.native(); | |
550 | } | |
551 | ||
552 | /// Very fast inequality check that compares the actual DLL/DSO objects. Throws nothing. | |
553 | inline bool operator!=(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT { | |
554 | return lhs.native() != rhs.native(); | |
555 | } | |
556 | ||
557 | /// Compare the actual DLL/DSO objects without any guarantee to be stable between runs. Throws nothing. | |
558 | inline bool operator<(const shared_library& lhs, const shared_library& rhs) BOOST_NOEXCEPT { | |
559 | return lhs.native() < rhs.native(); | |
560 | } | |
561 | ||
562 | /// Swaps two shared libraries. Does not invalidate symbols and functions loaded from libraries. Throws nothing. | |
563 | inline void swap(shared_library& lhs, shared_library& rhs) BOOST_NOEXCEPT { | |
564 | lhs.swap(rhs); | |
565 | } | |
566 | ||
567 | }} // boost::dll | |
568 | ||
569 | #endif // BOOST_DLL_SHARED_LIBRARY_HPP |