Cogs.Core
Module.Windows.cpp
1#include "Module.h"
2
3#include "Unicode.h"
4#include "../Logging/Logger.h"
5#include <array>
6#include <span>
7
8namespace
9{
10 const Cogs::Logging::Log logger = Cogs::Logging::getLogger("Module");
11
12
14 std::span<const char*> dllVersions() {
15#if defined( DEBUG )
16 static std::array paths = { ".Debug.dll" };
17 return std::span<const char*>(paths);
18#elif defined( OSOMP_EnableProfiler )
19 static std::array paths = { ".ReleaseMemProfile.dll", ".Release.dll" };
20 return std::span<const char*>(paths);
21#elif defined( ASAN )
22 static std::array paths = { ".ReleaseASan.dll", ".Release.dll" };
23 return std::span<const char*>(paths);
24#else
25 static std::array paths = { ".Release.dll" };
26 return std::span<const char*>(paths);
27#endif
28 }
29}
30
41void Cogs::Module::load(const std::string& path, LoadStatus& status, void*& handle) {
42 std::string fullPath = path;
43
44 if (fullPath.find(".dll") == std::string::npos) {
45#if defined( _WIN64 )
46 fullPath += ".x64";
47#else
48 fullPath += ".x32";
49#endif
50
51 std::span<const char*> versions = dllVersions();
52 std::string libraryPath;
53 libraryPath.reserve(fullPath.size() + 40);
54 for (const char* version : versions) {
55 libraryPath.clear();
56 libraryPath += fullPath;
57 libraryPath += version;
58 handle = LoadLibraryW(Cogs::widen(libraryPath).c_str());
59 if (handle) break;
60 }
61 if (!handle) {
62 fullPath = libraryPath;
63 }
64 }
65 else {
66 handle = LoadLibraryW(Cogs::widen(path).c_str());
67 }
68
69 if (!handle) {
70 DWORD error = GetLastError();
71 LPWSTR messageBuffer = nullptr;
72 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
73 nullptr,
74 error,
75 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
76 reinterpret_cast<LPWSTR>(&messageBuffer),
77 0,
78 nullptr);
79 std::string message = narrow(messageBuffer);
80 LocalFree(messageBuffer);
81 while (!message.empty() && (message.back() == '\r' || message.back() == '\n')) { message.pop_back(); }
82 LOG_ERROR(logger, "Failed to load %s: Error %#x: %s", fullPath.c_str(), GetLastError(), message.c_str());
83 }
84
85 status = handle ? LoadStatus::Loaded : LoadStatus::Failed;
86}
87
88void Cogs::Module::unload(void* handle) {
89 if (handle) {
90 FreeLibrary(static_cast<HMODULE>(handle));
91 }
92}
93
100void* Cogs::Module::getProcAddress(void* handle, const char* procName) {
101 return GetProcAddress(static_cast<HMODULE>(handle), procName);
102}
Log implementation class.
Definition: LogManager.h:139
static void load(const std::string &path, LoadStatus &status, void *&handle)
Attempts to load a shared library with the given name.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180