Back to home page

EIC code displayed by LXR

 
 

    


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