* do not move constant variables * applet_manager: avoid possible use after move * use constant references where pointed out by msvc * extra_hid: initialize response * ValidateSaveState: passing slot separately is not necessary * common: mark HashCombine as nodiscard * cityhash: remove use of using namespace std * Prefix all size_t with std:: done automatically by executing regex replace `([^:0-9a-zA-Z_])size_t([^0-9a-zA-Z_])` -> `$1std::size_t$2` based on 7d8f115 * shared_memory.cpp: fix log error format * fix compiling with pch off
99 lines
3.0 KiB
C++
99 lines
3.0 KiB
C++
// Copyright 2023 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <fmt/format.h>
|
|
#if defined(_WIN32)
|
|
#include <windows.h>
|
|
#else
|
|
#include <dlfcn.h>
|
|
#endif
|
|
#include "dynamic_library.h"
|
|
|
|
namespace Common {
|
|
|
|
DynamicLibrary::DynamicLibrary() = default;
|
|
|
|
DynamicLibrary::DynamicLibrary(void* handle_) : handle{handle_} {}
|
|
|
|
DynamicLibrary::DynamicLibrary(std::string_view name, int major, int minor) {
|
|
auto full_name = GetLibraryName(name, major, minor);
|
|
void(Load(full_name));
|
|
}
|
|
|
|
DynamicLibrary::~DynamicLibrary() {
|
|
if (handle) {
|
|
#if defined(_WIN32)
|
|
FreeLibrary(reinterpret_cast<HMODULE>(handle));
|
|
#else
|
|
dlclose(handle);
|
|
#endif // defined(_WIN32)
|
|
handle = nullptr;
|
|
}
|
|
}
|
|
|
|
bool DynamicLibrary::Load(std::string_view filename) {
|
|
#if defined(_WIN32)
|
|
handle = reinterpret_cast<void*>(LoadLibraryA(filename.data()));
|
|
if (!handle) {
|
|
DWORD error_message_id = GetLastError();
|
|
LPSTR message_buffer = nullptr;
|
|
std::size_t size =
|
|
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
nullptr, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
reinterpret_cast<LPSTR>(&message_buffer), 0, nullptr);
|
|
std::string message(message_buffer, size);
|
|
load_error = message;
|
|
return false;
|
|
}
|
|
#else
|
|
handle = dlopen(filename.data(), RTLD_LAZY);
|
|
if (!handle) {
|
|
load_error = dlerror();
|
|
return false;
|
|
}
|
|
#endif // defined(_WIN32)
|
|
return true;
|
|
}
|
|
|
|
void* DynamicLibrary::GetRawSymbol(std::string_view name) const {
|
|
#if defined(_WIN32)
|
|
return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(handle), name.data()));
|
|
#else
|
|
return dlsym(handle, name.data());
|
|
#endif // defined(_WIN32)
|
|
}
|
|
|
|
std::string DynamicLibrary::GetLibraryName(std::string_view name, int major, int minor) {
|
|
#if defined(_WIN32)
|
|
if (major >= 0 && minor >= 0) {
|
|
return fmt::format("{}-{}-{}.dll", name, major, minor);
|
|
} else if (major >= 0) {
|
|
return fmt::format("{}-{}.dll", name, major);
|
|
} else {
|
|
return fmt::format("{}.dll", name);
|
|
}
|
|
#elif defined(__APPLE__)
|
|
auto prefix = name.starts_with("lib") ? "" : "lib";
|
|
if (major >= 0 && minor >= 0) {
|
|
return fmt::format("{}{}.{}.{}.dylib", prefix, name, major, minor);
|
|
} else if (major >= 0) {
|
|
return fmt::format("{}{}.{}.dylib", prefix, name, major);
|
|
} else {
|
|
return fmt::format("{}{}.dylib", prefix, name);
|
|
}
|
|
#else
|
|
auto prefix = name.starts_with("lib") ? "" : "lib";
|
|
if (major >= 0 && minor >= 0) {
|
|
return fmt::format("{}{}.so.{}.{}", prefix, name, major, minor);
|
|
} else if (major >= 0) {
|
|
return fmt::format("{}{}.so.{}", prefix, name, major);
|
|
} else {
|
|
return fmt::format("{}{}.so", prefix, name);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
} // namespace Common
|