File indexing completed on 2025-09-16 08:30:35
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_DLL_SHARED_LIBRARY_IMPL_HPP
0009 #define BOOST_DLL_SHARED_LIBRARY_IMPL_HPP
0010
0011 #include <boost/dll/config.hpp>
0012 #include <boost/dll/shared_library_load_mode.hpp>
0013 #include <boost/dll/detail/aggressive_ptr_cast.hpp>
0014 #include <boost/dll/detail/system_error.hpp>
0015 #include <boost/dll/detail/windows/path_from_handle.hpp>
0016
0017 #include <boost/core/invoke_swap.hpp>
0018
0019 #include <boost/winapi/dll.hpp>
0020
0021 #include <utility> // std::move
0022
0023 #ifdef BOOST_HAS_PRAGMA_ONCE
0024 # pragma once
0025 #endif
0026
0027 namespace boost { namespace dll { namespace detail {
0028
0029 class shared_library_impl {
0030 public:
0031 typedef boost::winapi::HMODULE_ native_handle_t;
0032
0033 shared_library_impl() noexcept
0034 : shared_library_impl(nullptr)
0035 {}
0036
0037 ~shared_library_impl() noexcept {
0038 unload();
0039 }
0040
0041 shared_library_impl(shared_library_impl&& sl) noexcept
0042 : handle_(sl.handle_)
0043 {
0044 sl.handle_ = nullptr;
0045 }
0046
0047 explicit shared_library_impl(native_handle_t handle) noexcept
0048 : handle_(handle)
0049 {}
0050
0051 shared_library_impl & operator=(shared_library_impl&& sl) noexcept {
0052 swap(sl);
0053 return *this;
0054 }
0055
0056 static boost::dll::fs::path decorate(const boost::dll::fs::path& sl) {
0057 boost::dll::fs::path actual_path = sl;
0058 actual_path += suffix();
0059 return actual_path;
0060 }
0061
0062 void load(boost::dll::fs::path sl, load_mode::type portable_mode, std::error_code &ec) {
0063 typedef boost::winapi::DWORD_ native_mode_t;
0064 native_mode_t native_mode = static_cast<native_mode_t>(portable_mode);
0065 unload();
0066
0067 if (!sl.is_absolute() && !(native_mode & load_mode::search_system_folders)) {
0068 boost::dll::fs::error_code current_path_ec;
0069 boost::dll::fs::path prog_loc = boost::dll::fs::current_path(current_path_ec);
0070
0071 if (!current_path_ec) {
0072 prog_loc /= sl;
0073 sl.swap(prog_loc);
0074 }
0075 }
0076 native_mode = static_cast<unsigned>(native_mode) & ~static_cast<unsigned>(load_mode::search_system_folders);
0077
0078
0079 if (!!(native_mode & load_mode::append_decorations)) {
0080 native_mode = static_cast<unsigned>(native_mode) & ~static_cast<unsigned>(load_mode::append_decorations);
0081
0082 if (load_impl(decorate(sl), native_mode, ec)) {
0083 return;
0084 }
0085
0086
0087 const boost::dll::fs::path mingw_load_path = (
0088 sl.has_parent_path()
0089 ? sl.parent_path() / L"lib"
0090 : L"lib"
0091 ).native() + sl.filename().native() + suffix().native();
0092 if (load_impl(mingw_load_path, native_mode, ec)) {
0093 return;
0094 }
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104 if (sl.has_extension()) {
0105 handle_ = boost::winapi::LoadLibraryExW(sl.c_str(), 0, native_mode);
0106 } else {
0107 handle_ = boost::winapi::LoadLibraryExW((sl.native() + L".").c_str(), 0, native_mode);
0108 }
0109
0110
0111
0112 if (!handle_) {
0113 ec = boost::dll::detail::last_error_code();
0114 }
0115 }
0116
0117 bool is_loaded() const noexcept {
0118 return (handle_ != 0);
0119 }
0120
0121 void unload() noexcept {
0122 if (handle_) {
0123 boost::winapi::FreeLibrary(handle_);
0124 handle_ = 0;
0125 }
0126 }
0127
0128 void swap(shared_library_impl& rhs) noexcept {
0129 boost::core::invoke_swap(handle_, rhs.handle_);
0130 }
0131
0132 boost::dll::fs::path full_module_path(std::error_code &ec) const {
0133 return boost::dll::detail::path_from_handle(handle_, ec);
0134 }
0135
0136 static boost::dll::fs::path suffix() {
0137 return L".dll";
0138 }
0139
0140 void* symbol_addr(const char* sb, std::error_code &ec) const noexcept {
0141 if (is_resource()) {
0142
0143
0144
0145 ec = std::make_error_code(
0146 std::errc::operation_not_supported
0147 );
0148
0149 return nullptr;
0150 }
0151
0152
0153
0154
0155 void* const symbol = boost::dll::detail::aggressive_ptr_cast<void*>(
0156 boost::winapi::get_proc_address(handle_, sb)
0157 );
0158 if (symbol == nullptr) {
0159 ec = boost::dll::detail::last_error_code();
0160 }
0161
0162 return symbol;
0163 }
0164
0165 native_handle_t native() const noexcept {
0166 return handle_;
0167 }
0168
0169 private:
0170
0171 bool load_impl(const boost::dll::fs::path &load_path, boost::winapi::DWORD_ mode, std::error_code &ec) {
0172 handle_ = boost::winapi::LoadLibraryExW(load_path.c_str(), 0, mode);
0173 if (handle_) {
0174 return true;
0175 }
0176
0177 ec = boost::dll::detail::last_error_code();
0178 if (boost::dll::fs::exists(load_path)) {
0179
0180 return true;
0181 }
0182
0183 ec.clear();
0184 return false;
0185 }
0186
0187 bool is_resource() const noexcept {
0188 return false;
0189
0190
0191 }
0192
0193 native_handle_t handle_;
0194 };
0195
0196 }}}
0197
0198 #endif