#ifndef MODULES_HPP #define MODULES_HPP #include #include #include #if defined(_WIN32) || defined(_WIN64) #define PLATFORM_WINDOWS #define WIN32_LEAN_AND_MEAN #include #elif defined(__linux__) #define PLATFORM_LINUX #include #else #error "Unsupported platform (Windows and Linux only)." #endif using InitFunc = void(*)(); class ModuleManager { public: ModuleManager() = default; ~ModuleManager() { UnloadAll(); } ModuleManager(const ModuleManager&) = delete; ModuleManager& operator=(const ModuleManager&) = delete; bool LoadModule(const std::string& path, const std::string& initFuncName = "initialize") { if (modules.find(path) != modules.end()) { std::cerr << "[ModuleManager] Module is already loaded: " << path << std::endl; return false; } #if defined(PLATFORM_WINDOWS) HMODULE handle = LoadLibraryA(path.c_str()); if (!handle) { std::cerr << "[ModuleManager] Failed to load DLL (" << path << "): Code " << GetLastError() << std::endl; return false; } auto init = reinterpret_cast(GetProcAddress(handle, initFuncName.c_str())); if (!init) { std::cerr << "[ModuleManager] Function '" << initFuncName << "' not found in: " << path << std::endl; FreeLibrary(handle); return false; } #elif defined(PLATFORM_LINUX) void* handle = dlopen(path.c_str(), RTLD_NOW); if (!handle) { std::cerr << "[ModuleManager] Failed to load SO (" << path << "): " << dlerror() << std::endl; return false; } dlerror(); auto init = reinterpret_cast(dlsym(handle, initFuncName.c_str())); const char* dlsym_error = dlerror(); if (dlsym_error) { std::cerr << "[ModuleManager] Function '" << initFuncName << "' not found: " << dlsym_error << std::endl; dlclose(handle); return false; } #endif init(); modules[path] = handle; std::cout << "[ModuleManager] Module successfully loaded and initialized: " << path << std::endl; return true; } bool UnloadModule(const std::string& path) { auto it = modules.find(path); if (it == modules.end()) { return false; } #if defined(PLATFORM_WINDOWS) FreeLibrary(static_cast(it->second)); #elif defined(PLATFORM_LINUX) dlclose(it->second); #endif modules.erase(it); std::cout << "[ModuleManager] Module unloaded: " << path << std::endl; return true; } void UnloadAll() { for (auto& [path, handle] : modules) { #if defined(PLATFORM_WINDOWS) FreeLibrary(static_cast(handle)); #elif defined(PLATFORM_LINUX) dlclose(handle); #endif } modules.clear(); } private: #if defined(PLATFORM_WINDOWS) std::unordered_map modules; #elif defined(PLATFORM_LINUX) std::unordered_map modules; #endif }; #endif