/* ======================================== Copyright (C) 2025 Amlal El Mahrouss, licensed under the Apache 2.0 license ======================================== */ #pragma once #include #include #include namespace CompilerKit { class DLLLoader 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; } DLLLoader& operator()(const Char* path, const Char* entrypoint) { if (!path || !entrypoint) return *this; std::lock_guard lock(this->mMutex); if (this->mDLL) { this->Destroy(); } this->mDLL = ::dlopen(path, RTLD_LAZY); if (!this->mDLL) { return *this; } this->fEntrypoint = reinterpret_cast(::dlsym(this->mDLL, entrypoint)); if (!this->fEntrypoint) { this->Destroy(); return *this; } return *this; } NECTI_COPY_DELETE(DLLLoader) DLLLoader() = default; ~DLLLoader() { this->Destroy(); } private: void Destroy() noexcept { if (this->mDLL) { ::dlclose(this->mDLL); this->mDLL = nullptr; } this->fEntrypoint = nullptr; } }; } // namespace CompilerKit