45#include <system_error>
55 -> std::expected<void *, rtp::Error>
57 std::string safeNullTerminatedPath(path);
58 HMODULE handle = LoadLibraryA(safeNullTerminatedPath.c_str());
59 if (!handle) [[unlikely]] {
60 DWORD errorCode = GetLastError();
62 "LoadLibrary error: {} (code: {})",
63 std::system_category().message(errorCode), errorCode)};
66 return reinterpret_cast<void *
>(handle);
70 -> std::expected<void, rtp::Error>
72 if (!FreeLibrary(
reinterpret_cast<HMODULE
>(handle))) [[unlikely]] {
73 DWORD errorCode = GetLastError();
75 "FreeLibrary error: {} (code: {})",
76 std::system_category().message(errorCode), errorCode)};
83 -> std::expected<void *, rtp::Error>
86 "LoaderBackend: Handle cannot be null during symbol lookup");
87 RTP_ASSERT(!name.empty(),
"LoaderBackend: Symbol name cannot be empty");
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();
95 "GetProcAddress error: {} (code: {})",
96 std::system_category().message(errorCode), errorCode)};
99 return reinterpret_cast<void *
>(symbol);
Assertion and verification macros for runtime checks.
#define RTP_ASSERT(condition, msg,...)
Assertion macro (Debug mode)
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.