summaryrefslogtreecommitdiff
path: root/src/common/dynamic_library.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/dynamic_library.cpp')
-rw-r--r--src/common/dynamic_library.cpp106
1 files changed, 106 insertions, 0 deletions
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 @@
1// Copyright 2019 Dolphin Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#include <cstring>
6#include <string>
7#include <utility>
8
9#include <fmt/format.h>
10
11#include "common/dynamic_library.h"
12
13#ifdef _WIN32
14#include <windows.h>
15#else
16#include <dlfcn.h>
17#endif
18
19namespace Common {
20
21DynamicLibrary::DynamicLibrary() = default;
22
23DynamicLibrary::DynamicLibrary(const char* filename) {
24 Open(filename);
25}
26
27DynamicLibrary::DynamicLibrary(DynamicLibrary&& rhs) noexcept
28 : handle{std::exchange(rhs.handle, nullptr)} {}
29
30DynamicLibrary& DynamicLibrary::operator=(DynamicLibrary&& rhs) noexcept {
31 Close();
32 handle = std::exchange(rhs.handle, nullptr);
33 return *this;
34}
35
36DynamicLibrary::~DynamicLibrary() {
37 Close();
38}
39
40std::string DynamicLibrary::GetUnprefixedFilename(const char* filename) {
41#if defined(_WIN32)
42 return std::string(filename) + ".dll";
43#elif defined(__APPLE__)
44 return std::string(filename) + ".dylib";
45#else
46 return std::string(filename) + ".so";
47#endif
48}
49
50std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major, int minor) {
51#if defined(_WIN32)
52 if (major >= 0 && minor >= 0)
53 return fmt::format("{}-{}-{}.dll", libname, major, minor);
54 else if (major >= 0)
55 return fmt::format("{}-{}.dll", libname, major);
56 else
57 return fmt::format("{}.dll", libname);
58#elif defined(__APPLE__)
59 const char* prefix = std::strncmp(libname, "lib", 3) ? "lib" : "";
60 if (major >= 0 && minor >= 0)
61 return fmt::format("{}{}.{}.{}.dylib", prefix, libname, major, minor);
62 else if (major >= 0)
63 return fmt::format("{}{}.{}.dylib", prefix, libname, major);
64 else
65 return fmt::format("{}{}.dylib", prefix, libname);
66#else
67 const char* prefix = std::strncmp(libname, "lib", 3) ? "lib" : "";
68 if (major >= 0 && minor >= 0)
69 return fmt::format("{}{}.so.{}.{}", prefix, libname, major, minor);
70 else if (major >= 0)
71 return fmt::format("{}{}.so.{}", prefix, libname, major);
72 else
73 return fmt::format("{}{}.so", prefix, libname);
74#endif
75}
76
77bool DynamicLibrary::Open(const char* filename) {
78#ifdef _WIN32
79 handle = reinterpret_cast<void*>(LoadLibraryA(filename));
80#else
81 handle = dlopen(filename, RTLD_NOW);
82#endif
83 return handle != nullptr;
84}
85
86void DynamicLibrary::Close() {
87 if (!IsOpen())
88 return;
89
90#ifdef _WIN32
91 FreeLibrary(reinterpret_cast<HMODULE>(handle));
92#else
93 dlclose(handle);
94#endif
95 handle = nullptr;
96}
97
98void* DynamicLibrary::GetSymbolAddress(const char* name) const {
99#ifdef _WIN32
100 return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(handle), name));
101#else
102 return reinterpret_cast<void*>(dlsym(handle, name));
103#endif
104}
105
106} // namespace Common