DynamicLibrary: Add symbol resolution helpers

Less code bloat to loop over them.
This commit is contained in:
Stenzek
2026-05-16 14:22:03 +10:00
parent a2a12da4be
commit 22a3302faa
2 changed files with 93 additions and 2 deletions
+70 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
#include "common/dynamic_library.h"
@@ -164,6 +164,75 @@ void* DynamicLibrary::GetSymbolAddress(const char* name) const
#endif
}
bool DynamicLibrary::ResolveSymbols(const SymbolTable* symbols, size_t count, Error* error /* = nullptr */) const
{
for (size_t i = 0; i < count; i++)
{
if (!GetSymbol(symbols[i].name, symbols[i].ptr))
{
Error::SetStringFmt(error, "Failed to load symbol {} from library", symbols[i].name);
ClearSymbols(symbols, count);
return false;
}
}
return true;
}
bool DynamicLibrary::ResolveSymbols(const OptionalSymbolTable* symbols, size_t count, Error* error /* = nullptr */) const
{
for (size_t i = 0; i < count; i++)
{
if (!GetSymbol(symbols[i].name, symbols[i].ptr))
{
if (symbols[i].required)
{
Error::SetStringFmt(error, "Failed to load required symbol {} from library", symbols[i].name);
ClearSymbols(symbols, count);
return false;
}
else
{
WARNING_LOG("Failed to load optional symbol {} from library", symbols[i].name);
}
}
}
return true;
}
bool DynamicLibrary::ResolveSymbols(const std::span<const SymbolTable> symbols, Error* error /*= nullptr*/) const
{
return ResolveSymbols(symbols.data(), symbols.size(), error);
}
bool DynamicLibrary::ResolveSymbols(const std::span<const OptionalSymbolTable> symbols, Error* error /*= nullptr*/) const
{
return ResolveSymbols(symbols.data(), symbols.size(), error);
}
void DynamicLibrary::ClearSymbols(const SymbolTable* symbols, size_t count)
{
for (size_t i = 0; i < count; i++)
*symbols[i].ptr = nullptr;
}
void DynamicLibrary::ClearSymbols(const OptionalSymbolTable* symbols, size_t count)
{
for (size_t i = 0; i < count; i++)
*symbols[i].ptr = nullptr;
}
void DynamicLibrary::ClearSymbols(const std::span<const SymbolTable> symbols)
{
ClearSymbols(symbols.data(), symbols.size());
}
void DynamicLibrary::ClearSymbols(const std::span<const OptionalSymbolTable> symbols)
{
ClearSymbols(symbols.data(), symbols.size());
}
DynamicLibrary& DynamicLibrary::operator=(DynamicLibrary&& move)
{
Close();
+23 -1
View File
@@ -1,8 +1,9 @@
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
#pragma once
#include <span>
#include <string>
class Error;
@@ -67,6 +68,27 @@ public:
/// Returns the opaque OS-specific handle.
void* GetHandle() const { return m_handle; }
/// Symbol load helper.
struct SymbolTable
{
const char* name;
void** ptr;
};
struct OptionalSymbolTable
{
const char* name;
void** ptr;
bool required;
};
bool ResolveSymbols(const SymbolTable* symbols, size_t count, Error* error = nullptr) const;
bool ResolveSymbols(const OptionalSymbolTable* symbols, size_t count, Error* error = nullptr) const;
bool ResolveSymbols(const std::span<const SymbolTable> symbols, Error* error = nullptr) const;
bool ResolveSymbols(const std::span<const OptionalSymbolTable> symbols, Error* error = nullptr) const;
static void ClearSymbols(const SymbolTable* symbols, size_t count);
static void ClearSymbols(const OptionalSymbolTable* symbols, size_t count);
static void ClearSymbols(const std::span<const SymbolTable> symbols);
static void ClearSymbols(const std::span<const OptionalSymbolTable> symbols);
/// Move assignment, transfer ownership.
DynamicLibrary& operator=(DynamicLibrary&& move);