diff options
Diffstat (limited to 'include/CompilerKit/Utils/DLL.h')
| -rw-r--r-- | include/CompilerKit/Utils/DLL.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/include/CompilerKit/Utils/DLL.h b/include/CompilerKit/Utils/DLL.h new file mode 100644 index 0000000..6d12538 --- /dev/null +++ b/include/CompilerKit/Utils/DLL.h @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (See accompanying +// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0) +// Official repository: https://github.com/ne-foss-org/nectar + +#ifndef NECTAR_COMPILERKIT_UTILITIES_DLL_H +#define NECTAR_COMPILERKIT_UTILITIES_DLL_H + +#include <CompilerKit/Detail/Config.h> +#include <CompilerKit/Ref.h> +#include <dlfcn.h> +#include <mutex> + +namespace CompilerKit { + +#ifdef CK_POSIX +class ModuleLoader final { + public: + using EntryT = Int32 (*)(Int32 argc, char const* argv[]); + using HandleT = VoidPtr; + using MutexT = std::mutex; + + EntryT fEntrypoint{nullptr}; + + private: + HandleT mDLL{nullptr}; + MutexT mMutex; + + public: + explicit operator bool() { return this->mDLL != nullptr; } + + ModuleLoader& operator()(const std::string& path, const std::string& entrypoint) { + if (path.empty() || entrypoint.empty()) return *this; + + std::lock_guard<MutexT> lock(this->mMutex); + + if (this->mDLL) { + this->Reset(); + } + + this->mDLL = ::dlopen(path.data(), RTLD_LAZY); + + if (!this->mDLL) { + return *this; + } + + this->fEntrypoint = reinterpret_cast<EntryT>(::dlsym(this->mDLL, entrypoint.data())); + + if (!this->fEntrypoint) { + this->Reset(); + return *this; + } + + return *this; + } + + NECTAR_COPY_DELETE(ModuleLoader) + + ModuleLoader() = default; + ~ModuleLoader() { this->Reset(); } + + void Reset() noexcept { + if (this->mDLL) { + ::dlclose(this->mDLL); + this->mDLL = nullptr; + } + + this->fEntrypoint = nullptr; + } +}; + +using StrongDLLRef = StrongRef<ModuleLoader>; +using WeakDLLRef = WeakRef<ModuleLoader>; +#else +#error No ModuleLoader defined. +#endif + +} // namespace CompilerKit + +#endif // NECTAR_COMPILERKIT_UTILITIES_DLL_H |
