diff --git a/source/mijin/util/os.hpp b/source/mijin/util/os.hpp index 297a104..e02f0cd 100644 --- a/source/mijin/util/os.hpp +++ b/source/mijin/util/os.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../detect.hpp" namespace mijin @@ -41,6 +42,31 @@ struct LibraryHandle constexpr bool operator!() const noexcept { return data == nullptr; } }; +class SharedLibrary +{ +private: + LibraryHandle mHandle; +public: + SharedLibrary() noexcept = default; + SharedLibrary(const SharedLibrary&) = delete; + SharedLibrary(SharedLibrary&& other) noexcept : mHandle(std::exchange(other.mHandle, {})) {} + inline ~SharedLibrary() noexcept; + + SharedLibrary& operator=(const SharedLibrary&) = delete; + SharedLibrary& operator=(SharedLibrary&& other) noexcept + { + mHandle = std::exchange(other.mHandle, {}); + return *this; + } + + constexpr operator bool() const noexcept { return static_cast(mHandle); } + constexpr bool operator!() const noexcept { return !mHandle; } + + [[nodiscard]] inline bool open(std::string_view libraryFile) noexcept; + inline bool close() noexcept; + [[nodiscard]] inline void* loadSymbol(const char* symbolName) noexcept; +}; + // // public functions // @@ -52,6 +78,31 @@ void setCurrentThreadName(const char* threadName) noexcept; [[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) noexcept; +SharedLibrary::~SharedLibrary() noexcept +{ + close(); +} + +bool SharedLibrary::open(std::string_view libraryFile) noexcept +{ + close(); + mHandle = openSharedLibrary(libraryFile); + return static_cast(mHandle); +} + +bool SharedLibrary::close() noexcept +{ + if (mHandle) + { + return closeSharedLibrary(std::exchange(mHandle, {})); + } + return false; +} + +void* SharedLibrary::loadSymbol(const char* symbolName) noexcept +{ + return loadSymbolFromLibrary(mHandle, symbolName); +} } // namespace mijin #endif // !defined(MIJIN_UTIL_OS_HPP_INCLUDED)