#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 class ModuleManager { public: ModuleManager() = default; ~ModuleManager() { UnloadAll(); } ModuleManager(const ModuleManager&) = delete; ModuleManager& operator=(const ModuleManager&) = delete; void* GetOrLoadInitFunc(const std::string& path, const std::string& initFuncName = "initialize") { auto it = initFunctions.find(path); if (it != initFunctions.end()) { return it->second; } void* funcPtr = nullptr; #if defined(PLATFORM_WINDOWS) HMODULE handle = LoadLibraryA((path + ".dll").c_str()); if (!handle) { std::cerr << "[ModuleManager] Failed to load DLL (" << path << "): Code " << GetLastError() << std::endl; return nullptr; } funcPtr = reinterpret_cast(GetProcAddress(handle, initFuncName.c_str())); if (!funcPtr) { std::cerr << "[ModuleManager] Function '" << initFuncName << "' not found in: " << path << std::endl; FreeLibrary(handle); return nullptr; } #elif defined(PLATFORM_LINUX) void* handle = dlopen((path + ".so").c_str(), RTLD_NOW); if (!handle) { std::cerr << "[ModuleManager] Failed to load SO (" << path << "): " << dlerror() << std::endl; return nullptr; } dlerror(); funcPtr = 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 nullptr; } #endif modules[path] = handle; initFunctions[path] = funcPtr; std::cout << "[ModuleManager] Module loaded: " << path << std::endl; return funcPtr; } 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); initFunctions.erase(path); 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(); initFunctions.clear(); } private: #if defined(PLATFORM_WINDOWS) std::unordered_map modules; #elif defined(PLATFORM_LINUX) std::unordered_map modules; #endif std::unordered_map initFunctions; }; #endif