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

  1. 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).
  2. Confirm process bitness matches the native DLL (x64 vs x86) and the delegate's calling convention matches the export.
  3. Rebuild or update the ffxQueryDelegate declaration to match the SDK header signature for ffxQuery.
  4. 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

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


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)