// SPDX-FileCopyrightText: 2019 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include namespace Common { /** * 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. explicit DynamicLibrary(); /// Automatically loads the specified library. Call IsOpen() to check validity before use. explicit DynamicLibrary(const char* filename); /// Initializes the dynamic library with an already opened handle. explicit DynamicLibrary(void* handle_); /// Moves the library. DynamicLibrary(DynamicLibrary&&) noexcept; DynamicLibrary& operator=(DynamicLibrary&&) noexcept; /// Delete copies, we can't copy a dynamic library. DynamicLibrary(const DynamicLibrary&) = delete; DynamicLibrary& operator=(const DynamicLibrary&) = delete; /// Closes the library. ~DynamicLibrary(); /// Returns the specified library name with the platform-specific suffix added. [[nodiscard]] 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 [[nodiscard]] static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1); /// Returns true if a module is loaded, otherwise false. [[nodiscard]] bool IsOpen() const { return handle != nullptr; } /// Loads (or replaces) the handle with the specified library file name. /// Returns true if the library was loaded and can be used. [[nodiscard]] 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. [[nodiscard]] 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 [[nodiscard]] bool GetSymbol(const char* name, T* ptr) const { *ptr = reinterpret_cast(GetSymbolAddress(name)); return *ptr != nullptr; } private: /// Platform-dependent data type representing a dynamic library handle. void* handle = nullptr; }; } // namespace Common