|
|
|||
File indexing completed on 2025-10-27 08:16:00
0001 // Copyright 2014 Renato Tegon Forti, Antony Polukhin. 0002 // Copyright Antony Polukhin, 2015-2025. 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. 0005 // (See accompanying file LICENSE_1_0.txt 0006 // or copy at http://www.boost.org/LICENSE_1_0.txt) 0007 0008 #ifndef BOOST_DLL_IMPORT_HPP 0009 #define BOOST_DLL_IMPORT_HPP 0010 0011 #include <boost/dll/config.hpp> 0012 #include <boost/dll/shared_library.hpp> 0013 0014 #include <memory> // std::addressof 0015 #include <type_traits> 0016 0017 #ifdef BOOST_HAS_PRAGMA_ONCE 0018 # pragma once 0019 #endif 0020 0021 /// \file boost/dll/import.hpp 0022 /// \brief Contains all the boost::dll::import* reference counting 0023 /// functions that hold a shared pointer to the instance of 0024 /// boost::dll::shared_library. 0025 0026 namespace boost { namespace dll { 0027 0028 0029 namespace detail { 0030 0031 template <class T> 0032 class library_function { 0033 // Copying of `boost::dll::shared_library` is very expensive, so we use a `shared_ptr` to make it faster. 0034 boost::dll::detail::shared_ptr<T> f_; 0035 0036 public: 0037 inline library_function(const boost::dll::detail::shared_ptr<shared_library>& lib, T* func_ptr) noexcept 0038 : f_(lib, func_ptr) 0039 {} 0040 0041 // Compilation error at this point means that imported function 0042 // was called with unmatching parameters. 0043 // 0044 // Example: 0045 // auto f = dll::import_symbol<void(int)>("function", "lib.so"); 0046 // f("Hello"); // error: invalid conversion from 'const char*' to 'int' 0047 // f(1, 2); // error: too many arguments to function 0048 // f(); // error: too few arguments to function 0049 template <class... Args> 0050 inline auto operator()(Args&&... args) const 0051 -> decltype( (*f_)(static_cast<Args&&>(args)...) ) 0052 { 0053 return (*f_)(static_cast<Args&&>(args)...); 0054 } 0055 }; 0056 0057 template <class T> 0058 using import_type = typename std::conditional< 0059 std::is_object<T>::value, 0060 boost::dll::detail::shared_ptr<T>, 0061 boost::dll::detail::library_function<T> 0062 >::type; 0063 } // namespace detail 0064 0065 0066 #ifndef BOOST_DLL_DOXYGEN 0067 # define BOOST_DLL_IMPORT_RESULT_TYPE inline boost::dll::detail::import_type<T> 0068 #endif 0069 0070 0071 /*! 0072 * Returns callable object or std::shared_ptr<T> (boost::shared_ptr<T> if 0073 * BOOST_DLL_USE_BOOST_SHARED_PTR is defined) that holds the symbol imported 0074 * from the loaded library. Returned value refcounts usage 0075 * of the loaded shared library, so that it won't get unload until all copies of return value 0076 * are not destroyed. 0077 * 0078 * This call will succeed if call to \forcedlink{shared_library}`::has(const char* )` 0079 * function with the same symbol name returned `true`. 0080 * 0081 * For importing symbols by \b alias names use \forcedlink{import_alias} method. 0082 * 0083 * \b Examples: 0084 * 0085 * \code 0086 * std::function<int(int)> f = import_symbol<int(int)>("test_lib.so", "integer_func_name"); 0087 * 0088 * auto f_cpp11 = import_symbol<int(int)>("test_lib.so", "integer_func_name"); 0089 * \endcode 0090 * 0091 * \code 0092 * std::shared_ptr<int> i = import_symbol<int>("test_lib.so", "integer_name"); 0093 * \endcode 0094 * 0095 * \b Template \b parameter \b T: Type of the symbol that we are going to import. Must be explicitly specified. 0096 * 0097 * \param lib Path to shared library or shared library to load function from. 0098 * \param name Null-terminated C or C++ mangled name of the function to import. Can handle std::string, char*, const char*. 0099 * \param mode An mode that will be used on library load. 0100 * 0101 * \return callable object if T is a function type, or std::shared_ptr<T> (boost::shared_ptr<T> if 0102 * BOOST_DLL_USE_BOOST_SHARED_PTR is defined) if T is an object type. 0103 * 0104 * \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded. 0105 * Overload that accepts path also throws std::bad_alloc in case of insufficient memory. 0106 */ 0107 template <class T> 0108 BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, const char* name, 0109 load_mode::type mode = load_mode::default_mode) 0110 { 0111 using type = boost::dll::detail::import_type<T>; 0112 0113 auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib, mode); 0114 auto* addr = std::addressof(p->get<T>(name)); 0115 return type(std::move(p), addr); 0116 } 0117 0118 //! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0119 template <class T> 0120 BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const boost::dll::fs::path& lib, const std::string& name, 0121 load_mode::type mode = load_mode::default_mode) 0122 { 0123 return dll::import_symbol<T>(lib, name.c_str(), mode); 0124 } 0125 0126 //! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0127 template <class T> 0128 BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const char* name) { 0129 using type = boost::dll::detail::import_type<T>; 0130 0131 auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib); 0132 return type(p, std::addressof(p->get<T>(name))); 0133 } 0134 0135 //! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0136 template <class T> 0137 BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(const shared_library& lib, const std::string& name) { 0138 return dll::import_symbol<T>(lib, name.c_str()); 0139 } 0140 0141 //! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0142 template <class T> 0143 BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const char* name) { 0144 using type = boost::dll::detail::import_type<T>; 0145 0146 auto p = boost::dll::detail::make_shared<boost::dll::shared_library>( 0147 std::move(lib) 0148 ); 0149 auto* addr = std::addressof(p->get<T>(name)); 0150 return type(std::move(p), addr); 0151 } 0152 0153 //! \overload boost::dll::import_symbol(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0154 template <class T> 0155 BOOST_DLL_IMPORT_RESULT_TYPE import_symbol(shared_library&& lib, const std::string& name) { 0156 return dll::import_symbol<T>(std::move(lib), name.c_str()); 0157 } 0158 0159 0160 0161 0162 /*! 0163 * Returns callable object or std::shared_ptr<T> (boost::shared_ptr<T> if 0164 * BOOST_DLL_USE_BOOST_SHARED_PTR is defined) that holds the symbol imported 0165 * from the loaded library. Returned value refcounts usage 0166 * of the loaded shared library, so that it won't get unload until all copies of return value 0167 * are not destroyed. 0168 * 0169 * This call will succeed if call to \forcedlink{shared_library}`::has(const char* )` 0170 * function with the same symbol name returned `true`. 0171 * 0172 * For importing symbols by \b non \b alias names use \forcedlink{import} method. 0173 * 0174 * \b Examples: 0175 * 0176 * \code 0177 * std::function<int(int)> f = import_alias<int(int)>("test_lib.so", "integer_func_alias_name"); 0178 * 0179 * auto f_cpp11 = import_alias<int(int)>("test_lib.so", "integer_func_alias_name"); 0180 * \endcode 0181 * 0182 * \code 0183 * std::shared_ptr<int> i = import_alias<int>("test_lib.so", "integer_alias_name"); 0184 * \endcode 0185 * 0186 * \code 0187 * \endcode 0188 * 0189 * \b Template \b parameter \b T: Type of the symbol alias that we are going to import. Must be explicitly specified. 0190 * 0191 * \param lib Path to shared library or shared library to load function from. 0192 * \param name Null-terminated C or C++ mangled name of the function or variable to import. Can handle std::string, char*, const char*. 0193 * \param mode An mode that will be used on library load. 0194 * 0195 * \return callable object if T is a function type, or std::shared_ptr<T> (boost::shared_ptr<T> if 0196 * BOOST_DLL_USE_BOOST_SHARED_PTR is defined) if T is an object type. 0197 * 0198 * \throw \forcedlinkfs{system_error} if symbol does not exist or if the DLL/DSO was not loaded. 0199 * Overload that accepts path also throws std::bad_alloc in case of insufficient memory. 0200 */ 0201 template <class T> 0202 BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const char* name, 0203 load_mode::type mode = load_mode::default_mode) 0204 { 0205 using type = boost::dll::detail::import_type<T>; 0206 0207 auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib, mode); 0208 auto* addr = p->get<T*>(name); 0209 return type(std::move(p), addr); 0210 } 0211 0212 //! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0213 template <class T> 0214 BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const boost::dll::fs::path& lib, const std::string& name, 0215 load_mode::type mode = load_mode::default_mode) 0216 { 0217 return dll::import_alias<T>(lib, name.c_str(), mode); 0218 } 0219 0220 //! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0221 template <class T> 0222 BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const char* name) { 0223 using type = boost::dll::detail::import_type<T>; 0224 0225 auto p = boost::dll::detail::make_shared<boost::dll::shared_library>(lib); 0226 auto* addr = p->get<T*>(name); 0227 return type(std::move(p), addr); 0228 } 0229 0230 //! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0231 template <class T> 0232 BOOST_DLL_IMPORT_RESULT_TYPE import_alias(const shared_library& lib, const std::string& name) { 0233 return dll::import_alias<T>(lib, name.c_str()); 0234 } 0235 0236 //! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0237 template <class T> 0238 BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const char* name) { 0239 using type = boost::dll::detail::import_type<T>; 0240 0241 auto p = boost::dll::detail::make_shared<boost::dll::shared_library>( 0242 std::move(lib) 0243 ); 0244 auto* addr = p->get<T*>(name); 0245 return type(std::move(p), addr); 0246 } 0247 0248 //! \overload boost::dll::import_alias(const boost::dll::fs::path& lib, const char* name, load_mode::type mode) 0249 template <class T> 0250 BOOST_DLL_IMPORT_RESULT_TYPE import_alias(shared_library&& lib, const std::string& name) { 0251 return dll::import_alias<T>(std::move(lib), name.c_str()); 0252 } 0253 0254 #undef BOOST_DLL_IMPORT_RESULT_TYPE 0255 0256 0257 }} // boost::dll 0258 0259 #endif // BOOST_DLL_IMPORT_HPP 0260
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|