Air-Trap 1.0.0
A multiplayer R-Type clone game engine built with C++23 and ECS architecture
Loading...
Searching...
No Matches
LibraryBackend_Win.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** R-Type
4** File description:
5** LibraryBackend_Win.cpp, Windows-specific dynamic library handling
6*/
7
8/*
9** MIT License
10**
11** Copyright (c) 2025 Robin Toillon
12**
13** Permission is hereby granted, free of charge, to any person obtaining
14** a copy of this software and associated documentation files (the
15** "Software"), to deal in the Software without restriction, including
16** without limitation the rights to use, copy, modify, merge, publish,
17** distribute, sublicense, and/or sell copies of the Software, and to
18** permit persons to whom the Software is furnished to do so, subject to
19** the following conditions:
20**
21** The above copyright notice and this permission notice shall be
22** included in all copies or substantial portions of the Software.
23**
24** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31*/
32
42#include "RType/Assert.hpp"
43#include "LibraryBackend.hpp"
44
45#include <system_error>
46#include <windows.h>
47
48namespace rtp::sys::impl
49{
51 // Public API
53
54 auto LibraryBackend::open(std::string_view path)
55 -> std::expected<void *, rtp::Error>
56 {
57 std::string safeNullTerminatedPath(path);
58 HMODULE handle = LoadLibraryA(safeNullTerminatedPath.c_str());
59 if (!handle) [[unlikely]] {
60 DWORD errorCode = GetLastError();
61 return std::unexpected{Error::failure(ErrorCode::LibraryLoadFailed,
62 "LoadLibrary error: {} (code: {})",
63 std::system_category().message(errorCode), errorCode)};
64 }
65
66 return reinterpret_cast<void *>(handle);
67 }
68
69 auto LibraryBackend::close(void *handle) noexcept
70 -> std::expected<void, rtp::Error>
71 {
72 if (!FreeLibrary(reinterpret_cast<HMODULE>(handle))) [[unlikely]] {
73 DWORD errorCode = GetLastError();
74 return std::unexpected{Error::failure(ErrorCode::LibraryLoadFailed,
75 "FreeLibrary error: {} (code: {})",
76 std::system_category().message(errorCode), errorCode)};
77 }
78
79 return {};
80 }
81
82 auto LibraryBackend::getSymbol(void *handle, std::string_view name)
83 -> std::expected<void *, rtp::Error>
84 {
85 RTP_ASSERT(handle != nullptr,
86 "LoaderBackend: Handle cannot be null during symbol lookup");
87 RTP_ASSERT(!name.empty(), "LoaderBackend: Symbol name cannot be empty");
88
89 std::string safeNullTerminatedName(name);
90 FARPROC symbol = GetProcAddress(reinterpret_cast<HMODULE>(handle),
91 safeNullTerminatedName.c_str());
92 if (!symbol) [[unlikely]] {
93 DWORD errorCode = GetLastError();
94 return std::unexpected{Error::failure(ErrorCode::SymbolNotFound,
95 "GetProcAddress error: {} (code: {})",
96 std::system_category().message(errorCode), errorCode)};
97 }
98
99 return reinterpret_cast<void *>(symbol);
100 }
101}
Assertion and verification macros for runtime checks.
#define RTP_ASSERT(condition, msg,...)
Assertion macro (Debug mode)
Definition Assert.hpp:113
Declarations for platform-specific dynamic library handling.
static auto failure(ErrorCode code, std::format_string< Args... > fmt, Args &&...args) -> Error
Create a failure-level error.
static auto getSymbol(void *handle, std::string_view name) -> std::expected< void *, rtp::Error >
Get a symbol from the dynamic library.
static auto open(std::string_view path) -> std::expected< void *, rtp::Error >
Open a dynamic library from the given path.
static auto close(void *handle) noexcept -> std::expected< void, rtp::Error >
Close the dynamic library handle.
@ LibraryLoadFailed
Failed to load dynamic library.
@ SymbolNotFound
Symbol not found in dynamic library.