Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:44

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