#include "ModuleLoader.h" #include "Logger.h" #include #include #if _WIN32 #include #elif __linux__ #include #endif namespace sh::core { auto ModuleLoader::Load(const std::filesystem::path& moduleDir) -> std::optional { #if _WIN32 HMODULE handle = LoadLibraryExW(moduleDir.wstring().c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (handle == nullptr) { SH_ERROR_FORMAT("Error load module: {}", moduleDir.u8string()); return {}; } std::function fnInit{ GetProcAddress(handle, "Init") }; if (fnInit) fnInit(); std::function fnGetPluginInfo = reinterpret_cast(GetProcAddress(handle, "GetPluginInfo")); Plugin plugin{}; if (fnGetPluginInfo) { plugin = fnGetPluginInfo(); } #elif __linux__ void* handle = dlopen(moduleDir.c_str(), RTLD_LAZY); if (!handle) { SH_ERROR_FORMAT("Error load module: {}", moduleDir.u8string()); return {}; } std::function fnInit{ reinterpret_cast(dlsym(handle, "Init")) }; fnInit(); Plugin(*fnGetPluginInfo)() = (Plugin(*)())dlsym(handle, "GetPluginInfo"); Plugin plugin{}; if (fnGetPluginInfo) { plugin = fnGetPluginInfo(); } #endif plugin.handle = handle; plugin.path = moduleDir; return plugin; } SH_CORE_API void ModuleLoader::Clean(const Plugin& plugin) { if (plugin.handle == nullptr) return; #if _WIN32 auto result = FreeLibrary(reinterpret_cast(plugin.handle)); assert(result); #elif __linux__ auto result = dlclose(plugin.handle); assert(result); #endif } }