2015-04-05 31 views
6

Ich versuche, unmanaged printf-Like-Funktion mit DynamicMethod aufrufen. Zur Laufzeit bekomme ich eineAufruf varargs Methode über DynamicMethod

BadImageFormatException: Index nicht gefunden. (Ausnahme von HRESULT: 0x80131124)

Ist dies eine Begrenzung der Laufzeit oder mein emited Code ist falsch?

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(); 
    } 
} 
+2

Ich verglich dies mit der IL von 'printf ("% s =% d \ n ", __arglist (" a ", 0));' vom C# -Compiler generiert, und das funktioniert. Es ist ... genau das Gleiche wie das, was Ihr Code generiert außer "maxstack". Das ist seltsam, es ist die gleiche IL, es sollte genauso funktionieren. :/ –

+1

Das funktioniert tatsächlich, wenn ich eine Assembly, ein Modul und einen Typ manuell (mit den '-Builder' Typen) erstelle und dann die Methode aufruft. Seltsam. – svick

Antwort

4

Während die Ausnahme außerordentlich kryptisch ist, ich denke, es wegen einiger Sicherheitskontrollen Aufruf varargs Verfahren im Zusammenhang geworfen wird, oder es kann ein Fehler in ihnen sein. Was funktioniert, ist ein logisch zugeordnet Typ oder ein Modul zur Verfügung zu stellen:

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

fehlerlos dann funktioniert.

+0

Bestätigt, es funktioniert. Die [doc] (https://msdn.microsoft.com/en-us/library/System.Reflection.Emit.DynamicMethod.aspx) sagt * "Darüber hinaus können JIT Sichtbarkeitsprüfungen übersprungen werden." *, Sieht so aus verbunden. –