2020-03-16 23:48:53 +03:00
|
|
|
// Copyright 2019 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2+
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
#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) {
|
2020-08-16 13:17:30 +03:00
|
|
|
void(Open(filename));
|
2020-03-16 23:48:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Common
|