C#C
C#3y ago
peppy

✅ ✅ Vararg P/Invoke (x86) throws BadImageFormatException (0x80131124 "Index not found")

I am attempting to perform vararg P/Invokes following signatures I see on pinvoke.net and, e.g., https://stackoverflow.com/questions/2124490/what-is-the-proper-pinvoke-signature-for-a-function-that-takes-var-args

This led me to the following P/Invokes:
[DllImport("msvcrt.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int sprintf(IntPtr buffer, string format, __arglist);

[DllImport("msvcrt.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern int _scprintf(string format, __arglist);

invoked as such:
public static void CLRPrintfHook(string fmt, nint va0, nint va1, // ...
// {...}
_scprintf(fmt, __arglist(va0, va1));

specifically for
<PlatformTarget>x86</PlatformTarget>

using .NET 7.

But they result in a BadImageFormatException with result 0x80131124, "Index not found." See image. I do not have problems issuing P/Invokes to, e.g. _vscprintf and vsprintf which take va_list instead of varargs as the final argument.

For posterity, the working P/Invokes are declared as:
    [LibraryImport("msvcrt.dll", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller))]
    [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
    public static partial int _vscprintf(string format, IntPtr ptr);

    [LibraryImport("msvcrt.dll", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(System.Runtime.InteropServices.Marshalling.AnsiStringMarshaller))]
    [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
    public static partial int vsprintf(IntPtr buffer, string format, IntPtr args);


Any idea as to what I could be doing wrong? Or is this plain unsupported?
image.png
Was this page helpful?