#include "grbc/ext_dynamic.h" extern "C" { #include "dlopen.h" } #include "grbc/ext.h" #include "grbc/helpers.h" #include "grbc/spec.h" #include typedef const char *(*EXT_GetName)(); void EXT_dynamic_ext(const std::string &extension_name) { const std::array extension_paths = {"./grbc_ext", "C:\\grbc\\ext", "./", "./build"}; std::filesystem::path good_extension_path; for (size_t i = 0; i < extension_paths.size(); i++) { std::filesystem::path extension_path = std::filesystem::path(extension_paths[i]) / std::filesystem::path(extension_name + ".grbcext"); if (std::filesystem::exists(extension_path)) { good_extension_path = extension_path; break; } else { log_msg(("no extension at: " + extension_path.generic_string()).c_str()); } } if (good_extension_path.empty()) grbc_exception("Failed to find GRBC dynamic extension!"); struct hotwire_dll_t dll = hw_dlopen(good_extension_path.c_str(), 0x00002); EXT_HookInit hook_init = (EXT_HookInit)hw_dlsym(dll, "GRBC_Hook_Init"); EXT_GetName get_name = (EXT_GetName)hw_dlsym(dll, "GRBC_Get_Name"); if (hook_init == nullptr) grbc_exception( "Dynamic extension is missing public GRBC_Hook_Init symbol!"); if (get_name == nullptr) grbc_exception("Dynamic extension is missing public GRBC_Get_Name symbol!"); Extension ext{}; ext.name = get_name(); ext.hook_init = hook_init; log_msg( ("loaded dynamic extension from: " + good_extension_path.generic_string()) .c_str()); grbc_register_ext(ext); } void grbc_dynamic_init(sol::state &lua) { lua.set("grbc_dynamic_ext", EXT_dynamic_ext); log_msg("dynamic extension support loaded!"); } Extension grbc_dynamic() { Extension ext{}; ext.name = GRBC_EXT_dynamic_extensions_NAME; ext.hook_init = grbc_dynamic_init; return ext; }