mirror of
https://github.com/boostorg/dll.git
synced 2026-02-19 02:12:23 +00:00
Simplified code and unified load_mode::append_decorations behavior on different platforms
This commit is contained in:
@@ -60,9 +60,10 @@ public:
|
||||
}
|
||||
|
||||
void load(const boost::filesystem::path &sl, load_mode::type mode, boost::system::error_code &ec) {
|
||||
typedef int native_mode_t;
|
||||
unload();
|
||||
|
||||
// Do not allow opening NULL paths. User must use load_self() instead
|
||||
// Do not allow opening NULL paths. User must use program_location() instead
|
||||
if (sl.empty()) {
|
||||
ec = boost::system::error_code(
|
||||
boost::system::errc::bad_file_descriptor,
|
||||
@@ -73,17 +74,20 @@ public:
|
||||
}
|
||||
|
||||
// Fixing modes
|
||||
if (!(mode & RTLD_LAZY || mode & RTLD_NOW)) {
|
||||
if (!(mode & load_mode::rtld_now)) {
|
||||
mode |= load_mode::rtld_lazy;
|
||||
}
|
||||
|
||||
if (!(mode & RTLD_LOCAL || mode & RTLD_GLOBAL)) {
|
||||
if (!(mode & load_mode::rtld_global)) {
|
||||
mode |= load_mode::rtld_local;
|
||||
}
|
||||
|
||||
if (!(mode & load_mode::append_decorations)) {
|
||||
handle_ = dlopen(sl.c_str(), static_cast<int>(mode));
|
||||
} else {
|
||||
// Trying to open with appended decorations
|
||||
if (!!(mode & load_mode::append_decorations)) {
|
||||
mode = static_cast<load_mode::type>(
|
||||
static_cast<native_mode_t>(mode) & (~static_cast<native_mode_t>(load_mode::append_decorations))
|
||||
);
|
||||
|
||||
boost::filesystem::path actual_path = (
|
||||
std::strncmp(sl.filename().string().c_str(), "lib", 3)
|
||||
? (sl.parent_path() / "lib").native() + sl.filename().native()
|
||||
@@ -91,12 +95,14 @@ public:
|
||||
);
|
||||
actual_path += suffix();
|
||||
|
||||
handle_ = dlopen(
|
||||
actual_path.c_str(),
|
||||
static_cast<int>(mode) & (~static_cast<int>(load_mode::append_decorations))
|
||||
);
|
||||
handle_ = dlopen(actual_path.c_str(), static_cast<native_mode_t>(mode));
|
||||
if (handle_) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Opening by exactly specified path
|
||||
handle_ = dlopen(sl.c_str(), static_cast<native_mode_t>(mode));
|
||||
if (handle_) {
|
||||
return;
|
||||
}
|
||||
@@ -116,8 +122,8 @@ public:
|
||||
// named by the null-terminated string filename and returns an opaque
|
||||
// "handle" for the dynamic library. If filename is NULL, then the
|
||||
// returned handle is for the main program.
|
||||
handle_ = dlopen(NULL, static_cast<int>(mode) & (~static_cast<int>(load_mode::append_decorations)));
|
||||
ec.clear();
|
||||
handle_ = dlopen(NULL, static_cast<native_mode_t>(mode));
|
||||
if (!handle_) {
|
||||
ec = boost::system::error_code(
|
||||
boost::system::errc::bad_file_descriptor,
|
||||
|
||||
@@ -40,55 +40,59 @@ public:
|
||||
unload();
|
||||
}
|
||||
|
||||
shared_library_impl(BOOST_RV_REF(shared_library_impl) sl)
|
||||
{
|
||||
handle_ = sl.handle_; sl.handle_ = NULL;
|
||||
shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT
|
||||
: handle_(sl.handle_)
|
||||
{
|
||||
sl.handle_ = NULL;
|
||||
}
|
||||
|
||||
shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl)
|
||||
{
|
||||
handle_ = sl.handle_; sl.handle_ = NULL; return *this;
|
||||
shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT {
|
||||
handle_ = sl.handle_;
|
||||
sl.handle_ = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void load(const boost::filesystem::path &sl, load_mode::type mode, boost::system::error_code &ec) BOOST_NOEXCEPT {
|
||||
void load(const boost::filesystem::path &sl, load_mode::type mode, boost::system::error_code &ec) {
|
||||
typedef boost::detail::winapi::DWORD_ native_mode_t;
|
||||
unload();
|
||||
|
||||
boost::detail::winapi::DWORD_ flags = static_cast<boost::detail::winapi::DWORD_>(mode);
|
||||
// Trying to open with appended decorations
|
||||
if (!!(mode & load_mode::append_decorations)) {
|
||||
mode = static_cast<load_mode::type>(
|
||||
static_cast<native_mode_t>(mode) & (~static_cast<native_mode_t>(load_mode::append_decorations)
|
||||
);
|
||||
|
||||
// From MSDN: If the string specifies a module name without a path and the
|
||||
// file name extension is omitted, the function appends the default library
|
||||
// extension .dll to the module name.
|
||||
//
|
||||
// From experiments: Default library extension appended to the modukle name even if
|
||||
// we have some path. So we do not check for path, only for extension. We can not be sure that
|
||||
// such behavior remain across all platforms, so we add L".dll" by hand.
|
||||
const bool do_append_deco = !!(mode & load_mode::append_decorations);
|
||||
if (!do_append_deco && sl.has_extension()) {
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW(sl.c_str(), 0, flags);
|
||||
} else if (!do_append_deco) {
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW((sl.native() + L".").c_str(), 0, flags);
|
||||
} else {
|
||||
flags &= ~static_cast<boost::detail::winapi::DWORD_>(load_mode::append_decorations);
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW((sl.native() + L".dll").c_str(), 0, flags);
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW((sl.native() + L".dll").c_str(), 0, static_cast<native_mode_t>(mode));
|
||||
if (!handle_) {
|
||||
// MinGW loves 'lib' prefix and puts it even on Windows platform
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW(
|
||||
((sl.parent_path() / L"lib").native() + sl.filename().native() + L".dll").c_str(), 0, flags);
|
||||
((sl.parent_path() / L"lib").native() + sl.filename().native() + L".dll").c_str(),
|
||||
0,
|
||||
static_cast<native_mode_t>(mode)
|
||||
);
|
||||
}
|
||||
|
||||
if (handle_) {
|
||||
return;
|
||||
}
|
||||
|
||||
ec = boost::dll::detail::last_error_code();
|
||||
|
||||
// Possibly we were attempting to load an executable, then decorations must not be applied
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW(sl.c_str(), 0, flags);
|
||||
if (handle_) {
|
||||
ec.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// From MSDN: If the string specifies a module name without a path and the
|
||||
// file name extension is omitted, the function appends the default library
|
||||
// extension .dll to the module name.
|
||||
//
|
||||
// From experiments: Default library extension appended to the module name even if
|
||||
// we have some path. So we do not check for path, only for extension. We can not be sure that
|
||||
// such behavior remain across all platforms, so we add L".dll" by hand.
|
||||
if (sl.has_extension()) {
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW(sl.c_str(), 0, static_cast<native_mode_t>(mode));
|
||||
} else {
|
||||
handle_ = boost::detail::winapi::LoadLibraryExW((sl.native() + L".").c_str(), 0, static_cast<native_mode_t>(mode));
|
||||
}
|
||||
|
||||
// LoadLibraryExW method is capable of self loading from program_location() path. No special actions
|
||||
// must be taken to allow self loading.
|
||||
|
||||
if (!handle_) {
|
||||
ec = boost::dll::detail::last_error_code();
|
||||
}
|
||||
|
||||
@@ -192,11 +192,13 @@ enum type {
|
||||
*
|
||||
* \b Default: disabled
|
||||
*
|
||||
* Append a platform specific extension and prefix to shared_library filename.
|
||||
* Append a platform specific extension and prefix to shared library filename before trying to load it.
|
||||
* If load attempt fails, try to load with exactly specified name.
|
||||
*
|
||||
* \b Example:
|
||||
* \code
|
||||
* // Opens `./my_plugins/plugin1.dll` on Windows, `./my_plugins/libplugin1.so` on Linux and Apple
|
||||
* // Opens `./my_plugins/plugin1.dll` on Windows, `./my_plugins/libplugin1.so` on Linux, `./my_plugins/libplugin1.dylib` on MacOS.
|
||||
* // If that fails, loads `./my_plugins/plugin1`
|
||||
* boost::dll::shared_library lib("./my_plugins/plugin1", load_mode::append_decorations);
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user