#pragma once #if !defined(MIJIN_UTIL_OS_HPP_INCLUDED) #define MIJIN_UTIL_OS_HPP_INCLUDED 1 #include #include #include #include #include "../detect.hpp" #include "../types/result.hpp" namespace mijin { // // public defines // // // public constants // #if MIJIN_TARGET_OS == MIJIN_OS_LINUX inline const std::string_view LIBRARY_EXT = "so"; #elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS inline const std::string_view LIBRARY_EXT = "dll"; #else [[deprecated("OS not supported.")]] inline const int LIBRARY_EXT = 0; #endif // // public types // struct LibraryHandle { void* data = nullptr; constexpr operator bool() const noexcept { return data != nullptr; } 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 Result open(std::string_view libraryFile) noexcept; inline bool close() noexcept; [[nodiscard]] inline void* loadSymbol(const char* symbolName) noexcept; }; // // public functions // [[nodiscard]] Result openSharedLibrary(std::string_view libraryFile) noexcept; bool closeSharedLibrary(const LibraryHandle library) noexcept; [[nodiscard]] void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) noexcept; void setCurrentThreadName(const char* threadName) noexcept; [[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) noexcept; SharedLibrary::~SharedLibrary() noexcept { close(); } Result SharedLibrary::open(std::string_view libraryFile) noexcept { close(); Result openResult = openSharedLibrary(libraryFile); if (openResult.isSuccess()) { mHandle = openResult.getValue(); return true; } return ResultError(openResult.getError()); } 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)