{"record":{"id":"dab955b6b47024d2","repo":"beeradmoore/dlss-swapper","slug":"failed-to-get-function-delegate","errorCode":null,"errorMessage":"Failed to get function delegate","messagePattern":"Failed to get function delegate","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Helpers/FSR31/FSR31Helper.cs","lineNumber":49,"sourceCode":"        Logger.Info($\"AMDFidelityFXAPI - Loading {dllPath}\");\n        var hModule = LoadLibrary(dllPath);\n        if (hModule == IntPtr.Zero)\n        {\n            throw new Exception(\"Failed to load DLL\");\n        }\n\n        try\n        {\n            var pAddressOfFunctionToCall = GetProcAddress(hModule, \"ffxQuery\");\n            if (pAddressOfFunctionToCall == IntPtr.Zero)\n            {\n                throw new Exception(\"Failed to get function address\");\n            }\n\n            var ffxQuery = Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ffxQueryDelegate)) as ffxQueryDelegate;\n            if (ffxQuery is null)\n            {\n                throw new Exception(\"Failed to get function delegate\");\n            }\n\n            var versionQuery = new QueryDescGetVersions();\n\n            //versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;\n            versionQuery.createDescType = FxxConsts.FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;\n\n            // versionQuery.device = GetDX12Device(); // only for DirectX 12 applications\n            versionQuery.device = IntPtr.Zero;\n\n            // uint64_t versionCount = 0;\n            UInt64 versionCount = 0;\n            versionQuery.outputCount = Marshal.AllocHGlobal(sizeof(UInt64));\n            Marshal.WriteInt64(versionQuery.outputCount, (UInt32)versionCount);\n\n            Logger.Info(\"AMDFidelityFXAPI - Reading version count\");\n            // get number of versions for allocation\n            // ffxQuery(IntPtr.Zero, &versionQuery.header);","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/beeradmoore/dlss-swapper/blob/ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb/src/Helpers/FSR31/FSR31Helper.cs#L31-L67","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar ffxQuery = Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ffxQueryDelegate)) as ffxQueryDelegate;\n// after\nif (pAddressOfFunctionToCall == IntPtr.Zero) throw new Exception(\"ffxQuery not found in native library\");\nvar ffxQuery = Marshal.GetDelegateForFunctionPointer<ffxQueryDelegate>(pAddressOfFunctionToCall);\nif (ffxQuery is null) throw new Exception(\"Failed to get function delegate: signature/bitness mismatch with loaded FidelityFX DLL\");","handlingStrategy":"try-catch","validationCode":"if (pAddressOfFunctionToCall == IntPtr.Zero)\n    throw new InvalidOperationException(\"ffxQuery export not resolved; check FidelityFX DLL presence and bitness.\");\nvar modulePath = GetLoadedModulePath(\"amd_fidelityfx*\"); // confirm expected DLL version loaded","typeGuard":"bool IsValidFfxQueryDelegate(IntPtr ptr) => ptr != IntPtr.Zero && Marshal.GetDelegateForFunctionPointer<ffxQueryDelegate>(ptr) is not null;","tryCatchPattern":"try\n{\n    var ffxQuery = Marshal.GetDelegateForFunctionPointer<ffxQueryDelegate>(pAddressOfFunctionToCall);\n}\ncatch (Exception ex) when (ex is MarshalDirectiveException or EntryPointNotFoundException)\n{\n    // log loaded DLL version/bitness, surface actionable message\n}","preventionTips":["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)."],"tags":["native-interop","fsr31","pinvoke","dll"],"backgroundTag":"missing-dependency","analyzedSha":"ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb","analyzedAt":"2026-09-15T05:25:32.979Z","contentChangedAt":"2026-09-15T05:25:32.979Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}