Calling varargs method via DynamicMethod
Asked Answered
A

1

6

I'm trying to call unmanaged printf-like function using DynamicMethod. At runtime I get a

BadImageFormatException:Index not found. (Exception from HRESULT: 0x80131124)

Is this a limitation of runtime or my emited code is wrong?

public class Program
{
    [DllImport("msvcrt40.dll",CallingConvention = CallingConvention.Cdecl)]
    public static extern int printf(string format, __arglist);

    static void Main(string[] args) {

        var method = new DynamicMethod("printf", typeof(void), new Type[0], true);
        var il = method.GetILGenerator();

        il.Emit(OpCodes.Ldstr, " %s=%d\n");
        il.Emit(OpCodes.Ldstr, "a");
        il.Emit(OpCodes.Ldc_I4_0);
        il.EmitCall(OpCodes.Call, typeof(Program).GetMethod("printf", BindingFlags.Public | BindingFlags.Static), new Type[] { typeof(string), typeof(int) });
        il.Emit(OpCodes.Pop);
        il.Emit(OpCodes.Ret);

        var action = (Action)method.CreateDelegate(typeof(Action));
        action.Invoke();
    }
}
Atronna answered 5/4, 2015 at 15:0 Comment(2)
I compared this to the IL of printf(" %s=%d\n", __arglist("a", 0)); generated by the C# compiler, and which works. It's... exactly the same than what your code generates except for maxstack. That's weird, it's the same IL, it should work the same. :/Huddle
This actually works if I create an assembly, module and type manually (using the -Builder types) and then invoke the method. Weird.Trivia
E
4

While the exception is exceptionally cryptic, I guess it is thrown due to some security checks related to calling varargs method, or it may be a bug in them. What works is to provide a logically associated type or module:

var method = new DynamicMethod("printf", typeof(void), new Type[0], typeof(Program), true);

Works flawlessly then.

Epimorphosis answered 24/4, 2015 at 10:49 Comment(1)
Confirmed, it works. The doc says "In addition, JIT visibility checks can be skipped.", looks like it's related.Huddle

© 2022 - 2024 — McMap. All rights reserved.