{"record":{"id":"ca26345987a2bd0f","repo":"beeradmoore/dlss-swapper","slug":"failed-to-get-function-address","errorCode":null,"errorMessage":"Failed to get function address","messagePattern":"Failed to get function address","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Helpers/FSR31/FSR31Helper.cs","lineNumber":43,"sourceCode":"    public static List<string?> GetVersions(string dllPath)\n    {\n        if (Path.Exists(dllPath) == false)\n        {\n            return new List<string?>();\n        }\n        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;","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/beeradmoore/dlss-swapper/blob/ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb/src/Helpers/FSR31/FSR31Helper.cs#L25-L61","documentation":"FSR31Helper.GetVersions resolves the ffxQuery export from the already-loaded FidelityFX DLL using GetProcAddress. If the export is absent, GetProcAddress returns IntPtr.Zero and the helper throws 'Failed to get function address'. This means the DLL loaded fine but does not expose the expected entry point.","triggerScenarios":"Calling GetVersions against a FidelityFX/DLL build that predates the ffxQuery export (older FSR runtime), a wrong DLL file at dllPath (name matches but it is a different library), or a stripped/patched export table. Also when the helper targets FSR 3.1 API while the installed driver ships FSR 3.0 or an incompatible interface.","commonSituations":"Outdated AMD drivers without the FidelityFX API query interface; a DLL from a different SDK version where the function was renamed; grabbing a similarly named DLL (e.g. amd_fidelityfx_dx12 variants) that lacks ffxQuery.","solutions":["Update AMD Radeon/Adrenalin drivers to a version that ships the ffxQuery export (FSR 3.1+).","Verify the export exists before calling: check with dumpbin /exports or Dependencies tool on the exact dllPath file.","Confirm dllPath points to the intended FidelityFX API DLL, not a similarly named unrelated library.","Gracefully degrade: treat a missing ffxQuery as 'FSR version info unavailable' and return an empty list instead of throwing.","If supporting multiple SDK versions, probe for the export and fall back to older query functions."],"exampleFix":"// before\nvar pAddressOfFunctionToCall = GetProcAddress(hModule, \"ffxQuery\");\nif (pAddressOfFunctionToCall == IntPtr.Zero)\n    throw new Exception(\"Failed to get function address\");\n// after\nvar pAddressOfFunctionToCall = GetProcAddress(hModule, \"ffxQuery\");\nif (pAddressOfFunctionToCall == IntPtr.Zero)\n{\n    Logger.Warn($\"ffxQuery export not found in {dllPath}; FSR version info unavailable.\");\n    FreeLibrary(hModule);\n    return new List<string?>();\n}\n","handlingStrategy":"fallback","validationCode":"var h = LoadLibrary(dllPath);\nbool hasFfxQuery = h != IntPtr.Zero && GetProcAddress(h, \"ffxQuery\") != IntPtr.Zero;\nif (h != IntPtr.Zero) FreeLibrary(h);\nif (!hasFfxQuery) { /* use fallback version detection or skip */ }","typeGuard":"static bool HasExport(string dllPath, string export)\n{\n    var h = LoadLibrary(dllPath);\n    if (h == IntPtr.Zero) return false;\n    var ok = GetProcAddress(h, export) != IntPtr.Zero;\n    FreeLibrary(h);\n    return ok;\n}","tryCatchPattern":"try\n{\n    var versions = FSR31Helper.GetVersions();\n}\ncatch (Exception ex) when (ex.Message == \"Failed to get function address\")\n{\n    Logger.Warn(ex, \"DLL loaded but ffxQuery export missing (older FSR runtime); returning no versions.\");\n    versions = new List<string?>();\n}","preventionTips":["Probe for the export with GetProcAddress before binding a delegate, and degrade gracefully when absent.","Document the minimum driver/SDK version that provides ffxQuery and check for it at startup.","Verify the DLL's exports with dumpbin /exports when integrating a new FidelityFX build.","Never leak the loaded module handle on early-exit paths — always FreeLibrary before returning or throwing."],"tags":["native-interop","dll","fsr","pinvoke"],"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"}