From 7104e01bb3405369fc74a9c747c9038fc93cf6e3 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 16 Mar 2020 17:48:53 -0300 Subject: common/dynamic_library: Import and adapt helper from Dolphin --- src/common/dynamic_library.cpp | 106 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/common/dynamic_library.cpp (limited to 'src/common/dynamic_library.cpp') diff --git a/src/common/dynamic_library.cpp b/src/common/dynamic_library.cpp new file mode 100644 index 000000000..7ab54e9e4 --- /dev/null +++ b/src/common/dynamic_library.cpp @@ -0,0 +1,106 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include +#include + +#include + +#include "common/dynamic_library.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +namespace Common { + +DynamicLibrary::DynamicLibrary() = default; + +DynamicLibrary::DynamicLibrary(const char* filename) { + Open(filename); +} + +DynamicLibrary::DynamicLibrary(DynamicLibrary&& rhs) noexcept + : handle{std::exchange(rhs.handle, nullptr)} {} + +DynamicLibrary& DynamicLibrary::operator=(DynamicLibrary&& rhs) noexcept { + Close(); + handle = std::exchange(rhs.handle, nullptr); + return *this; +} + +DynamicLibrary::~DynamicLibrary() { + Close(); +} + +std::string DynamicLibrary::GetUnprefixedFilename(const char* filename) { +#if defined(_WIN32) + return std::string(filename) + ".dll"; +#elif defined(__APPLE__) + return std::string(filename) + ".dylib"; +#else + return std::string(filename) + ".so"; +#endif +} + +std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major, int minor) { +#if defined(_WIN32) + if (major >= 0 && minor >= 0) + return fmt::format("{}-{}-{}.dll", libname, major, minor); + else if (major >= 0) + return fmt::format("{}-{}.dll", libname, major); + else + return fmt::format("{}.dll", libname); +#elif defined(__APPLE__) + const char* prefix = std::strncmp(libname, "lib", 3) ? "lib" : ""; + if (major >= 0 && minor >= 0) + return fmt::format("{}{}.{}.{}.dylib", prefix, libname, major, minor); + else if (major >= 0) + return fmt::format("{}{}.{}.dylib", prefix, libname, major); + else + return fmt::format("{}{}.dylib", prefix, libname); +#else + const char* prefix = std::strncmp(libname, "lib", 3) ? "lib" : ""; + if (major >= 0 && minor >= 0) + return fmt::format("{}{}.so.{}.{}", prefix, libname, major, minor); + else if (major >= 0) + return fmt::format("{}{}.so.{}", prefix, libname, major); + else + return fmt::format("{}{}.so", prefix, libname); +#endif +} + +bool DynamicLibrary::Open(const char* filename) { +#ifdef _WIN32 + handle = reinterpret_cast(LoadLibraryA(filename)); +#else + handle = dlopen(filename, RTLD_NOW); +#endif + return handle != nullptr; +} + +void DynamicLibrary::Close() { + if (!IsOpen()) + return; + +#ifdef _WIN32 + FreeLibrary(reinterpret_cast(handle)); +#else + dlclose(handle); +#endif + handle = nullptr; +} + +void* DynamicLibrary::GetSymbolAddress(const char* name) const { +#ifdef _WIN32 + return reinterpret_cast(GetProcAddress(reinterpret_cast(handle), name)); +#else + return reinterpret_cast(dlsym(handle, name)); +#endif +} + +} // namespace Common -- cgit v1.2.3