#pragma once #include #include #include #include namespace I { using InstantiateInterfaceFn = void* (*)(); class CInterfaceReg { public: InstantiateInterfaceFn m_create_fn; const char* m_name; CInterfaceReg* m_next; }; inline const CInterfaceReg* Find(const char* module_name) { const HMODULE module_base = GetModuleHandleA(module_name); if (module_base == nullptr) return nullptr; const auto symbol = reinterpret_cast(GetProcAddress(module_base, "CreateInterface")); const std::uintptr_t list = symbol + *reinterpret_cast(symbol + 3) + 7; return *reinterpret_cast(list); } template T* Get(const char* module_name, const char* interface_partial_version) { for (const CInterfaceReg* current = Find(module_name); current; current = current->m_next) { if (std::string_view(current->m_name).find(interface_partial_version) != std::string_view::npos) { return reinterpret_cast(current->m_create_fn()); } } return nullptr; } }