Files
dlangvm/DlangVM/includes/modules.hpp
T
2026-10-12 23:34:28 +02:00

113 lines
3.1 KiB
C++

#ifndef MODULES_HPP
#define MODULES_HPP
#include <iostream>
#include <string>
#include <unordered_map>
#if defined(_WIN32) || defined(_WIN64)
#define PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(__linux__)
#define PLATFORM_LINUX
#include <dlfcn.h>
#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<InitFunc>(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<InitFunc>(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<HMODULE>(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<HMODULE>(handle));
#elif defined(PLATFORM_LINUX)
dlclose(handle);
#endif
}
modules.clear();
}
private:
#if defined(PLATFORM_WINDOWS)
std::unordered_map<std::string, HMODULE> modules;
#elif defined(PLATFORM_LINUX)
std::unordered_map<std::string, void*> modules;
#endif
};
#endif