| |
| |
|
|
| #include <string> |
| #include <utility> |
|
|
| #include <fmt/format.h> |
|
|
| #include "common/dynamic_library.h" |
|
|
| #ifdef _WIN32 |
| #include <windows.h> |
| #else |
| #include <dlfcn.h> |
| #endif |
|
|
| namespace Common { |
|
|
| DynamicLibrary::DynamicLibrary() = default; |
|
|
| DynamicLibrary::DynamicLibrary(const char* filename) { |
| void(Open(filename)); |
| } |
|
|
| DynamicLibrary::DynamicLibrary(void* handle_) : handle{handle_} {} |
|
|
| 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<void*>(LoadLibraryA(filename)); |
| #else |
| handle = dlopen(filename, RTLD_NOW); |
| #endif |
| return handle != nullptr; |
| } |
|
|
| void DynamicLibrary::Close() { |
| if (!IsOpen()) |
| return; |
|
|
| #ifdef _WIN32 |
| FreeLibrary(reinterpret_cast<HMODULE>(handle)); |
| #else |
| dlclose(handle); |
| #endif |
| handle = nullptr; |
| } |
|
|
| void* DynamicLibrary::GetSymbolAddress(const char* name) const { |
| #ifdef _WIN32 |
| return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(handle), name)); |
| #else |
| return reinterpret_cast<void*>(dlsym(handle, name)); |
| #endif |
| } |
|
|
| } |
|
|