2015-04-05 5 views
6

Я пытаюсь вызвать неуправляемую функцию, подобную printf, используя DynamicMethod. Во время выполнения я получаюВызов метода varargs через DynamicMethod

BadImageFormatException: индекс не найден. (Исключение из HRESULT: 0x80131124 )

Является ли это ограничение выполнения или мой emited код не так?

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

Я сравнил это с IL 'printf ("% s =% d \ n ", __arglist (" a ", 0));' сгенерирован компилятором C# и работает. Это точно так же, как то, что генерирует ваш код, кроме 'maxstack'. Это странно, это тот же ИЛ, он должен работать одинаково. :/ –

+1

Это действительно работает, если я создаю сборку, модуль и тип вручную (используя типы '-Builder'), а затем вызывается метод. Weird. – svick

ответ

4

Хотя исключение исключительно загадочное, я предполагаю, что это брошено из-за некоторые проверки безопасности, связанные с вызовом метода переменных аргументов, или это может быть ошибкой в ​​них. Что работает, чтобы обеспечить логически связанный тип или модуль:

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

Работает безупречно.

+0

Подтверждено, оно работает. В документе [doc] (https://msdn.microsoft.com/en-us/library/System.Reflection.Emit.DynamicMethod.aspx) говорится: «Кроме того, проверка доступности JIT может быть пропущена». *, Похоже, что это Связанный. –