dynamic_library.h (2868B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include <string> 7 8 class Error; 9 10 /** 11 * Provides a platform-independent interface for loading a dynamic library and retrieving symbols. 12 * The interface maintains an internal reference count to allow one handle to be shared between 13 * multiple users. 14 */ 15 class DynamicLibrary final 16 { 17 public: 18 /// Default constructor, does not load a library. 19 DynamicLibrary(); 20 21 /// Automatically loads the specified library. Call IsOpen() to check validity before use. 22 DynamicLibrary(const char* filename); 23 24 /// Move constructor, transfers ownership. 25 DynamicLibrary(DynamicLibrary&& move); 26 27 /// Closes the library. 28 ~DynamicLibrary(); 29 30 /// Returns the specified library name with the platform-specific suffix added. 31 static std::string GetUnprefixedFilename(const char* filename); 32 33 /// Returns the specified library name in platform-specific format. 34 /// Major/minor versions will not be included if set to -1. 35 /// If libname already contains the "lib" prefix, it will not be added again. 36 /// Windows: LIBNAME-MAJOR-MINOR-PATCH.dll 37 /// Linux: libLIBNAME.so.MAJOR.MINOR.PATCH 38 /// Mac: libLIBNAME.MAJOR.MINOR.PATCH.dylib 39 static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1, int patch = -1); 40 41 /// Returns true if a module is loaded, otherwise false. 42 bool IsOpen() const { return m_handle != nullptr; } 43 44 /// Loads (or replaces) the handle with the specified library file name. 45 /// Returns true if the library was loaded and can be used. 46 bool Open(const char* filename, Error* error); 47 48 /// Adopts, or takes ownership of an existing opened library. 49 void Adopt(void* handle); 50 51 /// Unloads the library, any function pointers from this library are no longer valid. 52 void Close(); 53 54 /// Returns the address of the specified symbol (function or variable) as an untyped pointer. 55 /// If the specified symbol does not exist in this library, nullptr is returned. 56 void* GetSymbolAddress(const char* name) const; 57 58 /// Obtains the address of the specified symbol, automatically casting to the correct type. 59 /// Returns true if the symbol was found and assigned, otherwise false. 60 template<typename T> 61 bool GetSymbol(const char* name, T* ptr) const 62 { 63 *ptr = reinterpret_cast<T>(GetSymbolAddress(name)); 64 return *ptr != nullptr; 65 } 66 67 /// Returns the opaque OS-specific handle. 68 void* GetHandle() const { return m_handle; } 69 70 /// Move assignment, transfer ownership. 71 DynamicLibrary& operator=(DynamicLibrary&& move); 72 73 private: 74 DynamicLibrary(const DynamicLibrary&) = delete; 75 DynamicLibrary& operator=(const DynamicLibrary&) = delete; 76 77 /// Platform-dependent data type representing a dynamic library handle. 78 void* m_handle = nullptr; 79 };