beeradmoore/dlss-swapper · error · Exception
Failed to get function delegate
Error message
Failed to get function delegate
What it means
FSR31Helper.GetVersions resolves the ffxQuery function pointer from the AMD FidelityFX SDK native library and converts it to a managed delegate via Marshal.GetDelegateForFunctionPointer. When the conversion returns null the helper cannot invoke the native API at all, so it throws this exception. It indicates the pointer existed but could not be marshaled to the expected ffxQueryDelegate signature.
Solutions
- Verify the correct FidelityFX SDK native DLL (matching the version the C# bindings target) is next to the executable and is the one actually loaded (check loaded modules, PATH order).
- Confirm process bitness matches the native DLL (x64 vs x86) and the delegate's calling convention matches the export.
- Rebuild or update the ffxQueryDelegate declaration to match the SDK header signature for ffxQuery.
- Log/inspect the raw pointer address to confirm a real export was resolved before marshaling.
Example fix
// before
var ffxQuery = Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ffxQueryDelegate)) as ffxQueryDelegate;
// after
if (pAddressOfFunctionToCall == IntPtr.Zero) throw new Exception("ffxQuery not found in native library");
var ffxQuery = Marshal.GetDelegateForFunctionPointer<ffxQueryDelegate>(pAddressOfFunctionToCall);
if (ffxQuery is null) throw new Exception("Failed to get function delegate: signature/bitness mismatch with loaded FidelityFX DLL"); Defensive patterns
Strategy: try-catch
Validate before calling
if (pAddressOfFunctionToCall == IntPtr.Zero)
throw new InvalidOperationException("ffxQuery export not resolved; check FidelityFX DLL presence and bitness.");
var modulePath = GetLoadedModulePath("amd_fidelityfx*"); // confirm expected DLL version loaded Type guard
bool IsValidFfxQueryDelegate(IntPtr ptr) => ptr != IntPtr.Zero && Marshal.GetDelegateForFunctionPointer<ffxQueryDelegate>(ptr) is not null;
Try / catch
try
{
var ffxQuery = Marshal.GetDelegateForFunctionPointer<ffxQueryDelegate>(pAddressOfFunctionToCall);
}
catch (Exception ex) when (ex is MarshalDirectiveException or EntryPointNotFoundException)
{
// log loaded DLL version/bitness, surface actionable message
} Prevention
- Pin and ship the exact FidelityFX SDK DLL version the bindings were generated against.
- Assert process bitness matches the native DLL at startup.
- Keep ffxQueryDelegate signature in sync with the SDK header (calling convention included).
When it happens
Trigger: Marshal.GetDelegateForFunctionPointer returns null for the pointer obtained from the native library — typically when the exported function's calling convention or signature does not match the ffxQueryDelegate P/Invoke signature, or a stale/incorrect FidelityFX DLL is loaded that exports a symbol at that address with an incompatible layout.
Common situations: Mixing FSR 3.1 SDK DLL versions (e.g. an older amd_fidelityfx_dx12.dll on PATH than the one the bindings were generated against); loading a 32-bit DLL into a 64-bit process or vice versa; architecture/ABI mismatch between the managed delegate definition and the native export.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Failed to get function address
- Failed to load DLL
- Failed to get version count. Return code
- LibraryPage_ZipDidNotContainAnyDlls
- GamePage_CouldNotFindGameInstallPathTemplate
AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15).
Data as JSON: /api/errors/dab955b6b47024d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Helpers/FSR31/FSR31Helper.cs:49
Logger.Info($"AMDFidelityFXAPI - Loading {dllPath}");
var hModule = LoadLibrary(dllPath);
if (hModule == IntPtr.Zero)
{
throw new Exception("Failed to load DLL");
}
try
{
var pAddressOfFunctionToCall = GetProcAddress(hModule, "ffxQuery");
if (pAddressOfFunctionToCall == IntPtr.Zero)
{
throw new Exception("Failed to get function address");
}
var ffxQuery = Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ffxQueryDelegate)) as ffxQueryDelegate;
if (ffxQuery is null)
{
throw new Exception("Failed to get function delegate");
}
var versionQuery = new QueryDescGetVersions();
//versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
versionQuery.createDescType = FxxConsts.FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
// versionQuery.device = GetDX12Device(); // only for DirectX 12 applications
versionQuery.device = IntPtr.Zero;
// uint64_t versionCount = 0;
UInt64 versionCount = 0;
versionQuery.outputCount = Marshal.AllocHGlobal(sizeof(UInt64));
Marshal.WriteInt64(versionQuery.outputCount, (UInt32)versionCount);
Logger.Info("AMDFidelityFXAPI - Reading version count");
// get number of versions for allocation
// ffxQuery(IntPtr.Zero, &versionQuery.header);View on GitHub (pinned to ab9b1e2d4b)