diff --git a/common/DynamicLibrary.cpp b/common/DynamicLibrary.cpp index 473f388b21..c82bb50637 100644 --- a/common/DynamicLibrary.cpp +++ b/common/DynamicLibrary.cpp @@ -1,9 +1,11 @@ -// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team +// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team // SPDX-License-Identifier: LGPL-3.0+ #include "common/DynamicLibrary.h" #include "common/Assertions.h" #include "common/Console.h" +#include "common/Error.h" +#include "common/SmallString.h" #include "common/StringUtil.h" #include @@ -15,13 +17,13 @@ #include #endif -using namespace Common; - DynamicLibrary::DynamicLibrary() = default; DynamicLibrary::DynamicLibrary(const char* filename) { - Open(filename); + Error error; + if (!Open(filename, &error)) + Console.ErrorFmt("DynamicLibrary open failed: {}", error.GetDescription()); } DynamicLibrary::DynamicLibrary(DynamicLibrary&& move) @@ -74,13 +76,13 @@ std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major, #endif } -bool DynamicLibrary::Open(const char* filename) +bool DynamicLibrary::Open(const char* filename, Error* error) { #ifdef _WIN32 m_handle = reinterpret_cast(LoadLibraryW(StringUtil::UTF8StringToWideString(filename).c_str())); if (!m_handle) { - Console.Error(fmt::format("(DynamicLibrary) Loading {} failed: {}", filename, GetLastError())); + Error::SetWin32(error, TinyString::from_fmt("Loading {} failed: ", filename), GetLastError()); return false; } @@ -90,7 +92,7 @@ bool DynamicLibrary::Open(const char* filename) if (!m_handle) { const char* err = dlerror(); - Console.Error(fmt::format("(DynamicLibrary) Loading {} failed: {}", filename, err ? err : "")); + Error::SetStringFmt(error, "Loading {} failed: {}", filename, err ? err : ""); return false; } diff --git a/common/DynamicLibrary.h b/common/DynamicLibrary.h index 18f54eaefc..65082912ab 100644 --- a/common/DynamicLibrary.h +++ b/common/DynamicLibrary.h @@ -1,74 +1,73 @@ -// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team +// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team // SPDX-License-Identifier: LGPL-3.0+ #pragma once + #include -namespace Common +class Error; + +/** + * Provides a platform-independent interface for loading a dynamic library and retrieving symbols. + * The interface maintains an internal reference count to allow one handle to be shared between + * multiple users. + */ +class DynamicLibrary final { - /** - * Provides a platform-independent interface for loading a dynamic library and retrieving symbols. - * The interface maintains an internal reference count to allow one handle to be shared between - * multiple users. - */ - class DynamicLibrary final +public: + /// Default constructor, does not load a library. + DynamicLibrary(); + + /// Automatically loads the specified library. Call IsOpen() to check validity before use. + DynamicLibrary(const char* filename); + + /// Move constructor, transfers ownership. + DynamicLibrary(DynamicLibrary&& move); + + /// Closes the library. + ~DynamicLibrary(); + + /// Returns the specified library name with the platform-specific suffix added. + static std::string GetUnprefixedFilename(const char* filename); + + /// Returns the specified library name in platform-specific format. + /// Major/minor versions will not be included if set to -1. + /// If libname already contains the "lib" prefix, it will not be added again. + /// Windows: LIBNAME-MAJOR-MINOR.dll + /// Linux: libLIBNAME.so.MAJOR.MINOR + /// Mac: libLIBNAME.MAJOR.MINOR.dylib + static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1); + + /// Returns true if a module is loaded, otherwise false. + bool IsOpen() const { return m_handle != nullptr; } + + /// Loads (or replaces) the handle with the specified library file name. + /// Returns true if the library was loaded and can be used. + bool Open(const char* filename, Error* error); + + /// Unloads the library, any function pointers from this library are no longer valid. + void Close(); + + /// Returns the address of the specified symbol (function or variable) as an untyped pointer. + /// If the specified symbol does not exist in this library, nullptr is returned. + void* GetSymbolAddress(const char* name) const; + + /// Obtains the address of the specified symbol, automatically casting to the correct type. + /// Returns true if the symbol was found and assigned, otherwise false. + template + bool GetSymbol(const char* name, T* ptr) const { - public: - /// Default constructor, does not load a library. - DynamicLibrary(); + *ptr = reinterpret_cast(GetSymbolAddress(name)); + return *ptr != nullptr; + } - /// Automatically loads the specified library. Call IsOpen() to check validity before use. - DynamicLibrary(const char* filename); + /// Move assignment, transfer ownership. + DynamicLibrary& operator=(DynamicLibrary&& move); - /// Move constructor, transfers ownership. - DynamicLibrary(DynamicLibrary&& move); +private: + DynamicLibrary(const DynamicLibrary&) = delete; + DynamicLibrary& operator=(const DynamicLibrary&) = delete; - /// Closes the library. - ~DynamicLibrary(); - - /// Returns the specified library name with the platform-specific suffix added. - static std::string GetUnprefixedFilename(const char* filename); - - /// Returns the specified library name in platform-specific format. - /// Major/minor versions will not be included if set to -1. - /// If libname already contains the "lib" prefix, it will not be added again. - /// Windows: LIBNAME-MAJOR-MINOR.dll - /// Linux: libLIBNAME.so.MAJOR.MINOR - /// Mac: libLIBNAME.MAJOR.MINOR.dylib - static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1); - - /// Returns true if a module is loaded, otherwise false. - bool IsOpen() const { return m_handle != nullptr; } - - /// Loads (or replaces) the handle with the specified library file name. - /// Returns true if the library was loaded and can be used. - bool Open(const char* filename); - - /// Unloads the library, any function pointers from this library are no longer valid. - void Close(); - - /// Returns the address of the specified symbol (function or variable) as an untyped pointer. - /// If the specified symbol does not exist in this library, nullptr is returned. - void* GetSymbolAddress(const char* name) const; - - /// Obtains the address of the specified symbol, automatically casting to the correct type. - /// Returns true if the symbol was found and assigned, otherwise false. - template - bool GetSymbol(const char* name, T* ptr) const - { - *ptr = reinterpret_cast(GetSymbolAddress(name)); - return *ptr != nullptr; - } - - /// Move assignment, transfer ownership. - DynamicLibrary& operator=(DynamicLibrary&& move); - - private: - DynamicLibrary(const DynamicLibrary&) = delete; - DynamicLibrary& operator=(const DynamicLibrary&) = delete; - - /// Platform-dependent data type representing a dynamic library handle. - void* m_handle = nullptr; - }; - -} // namespace Common \ No newline at end of file + /// Platform-dependent data type representing a dynamic library handle. + void* m_handle = nullptr; +}; diff --git a/pcsx2/GS/GSCapture.cpp b/pcsx2/GS/GSCapture.cpp index fd274fe465..6ecb2fa846 100644 --- a/pcsx2/GS/GSCapture.cpp +++ b/pcsx2/GS/GSCapture.cpp @@ -222,11 +222,11 @@ VISIT_SWRESAMPLE_IMPORTS(DECLARE_IMPORT); #ifndef USE_LINKED_FFMPEG static void UnloadFFmpegFunctions(std::unique_lock& lock); -static Common::DynamicLibrary s_avcodec_library; -static Common::DynamicLibrary s_avformat_library; -static Common::DynamicLibrary s_avutil_library; -static Common::DynamicLibrary s_swscale_library; -static Common::DynamicLibrary s_swresample_library; +static DynamicLibrary s_avcodec_library; +static DynamicLibrary s_avformat_library; +static DynamicLibrary s_avutil_library; +static DynamicLibrary s_swscale_library; +static DynamicLibrary s_swresample_library; static bool s_library_loaded = false; static std::mutex s_load_mutex; @@ -236,9 +236,9 @@ bool GSCapture::LoadFFmpeg(bool report_errors) if (s_library_loaded) return true; - const auto open_dynlib = [](Common::DynamicLibrary& lib, const char* name, int major_version) { - std::string full_name(Common::DynamicLibrary::GetVersionedFilename(name, major_version)); - return lib.Open(full_name.c_str()); + const auto open_dynlib = [](DynamicLibrary& lib, const char* name, int major_version) { + std::string full_name(DynamicLibrary::GetVersionedFilename(name, major_version)); + return lib.Open(full_name.c_str(), nullptr); }; bool result = true;