Как передать параметр Struct при вызове динамического метода в C#?

У меня проблемы с передачей параметра структуры в динамическом методе. Вот мой код:

public class Program
{
    static void Main(string[] args)
    {
        var DynamicAssembly = new AssemblyName();
        DynamicAssembly.Name = "DynamicTypes";
        AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(DynamicAssembly, AssemblyBuilderAccess.Run);
        ModuleBuilder mb = ab.DefineDynamicModule(DynamicAssembly.Name);
        TypeBuilder tb = mb.DefineType("Handler", TypeAttributes.Class | TypeAttributes.Public);
        MethodBuilder handler = tb.DefineMethod($"DynamicHandler",
            MethodAttributes.Public | MethodAttributes.Static,
           typeof(void),
           new Type[] { typeof(MyClass), typeof(MyStruct) });
        var ProcessMethod = typeof(Program).GetMethod(nameof(Process));
        ILGenerator il = handler.GetILGenerator();
        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldarg_1);
        il.EmitCall(OpCodes.Call, ProcessMethod, null);
        il.Emit(OpCodes.Nop);
        il.Emit(OpCodes.Ret);
        var DynamicType = tb.CreateType();
        MethodInfo methodInfo = DynamicType.GetMethod("DynamicHandler");
        int i = 100;
        while (true)
        {
            i++;
            MyClass a = new MyClass()
            {
                a = i,
            };
            MyStruct b = new MyStruct()
            {
                b = i,
            };
            methodInfo.Invoke(null, new object[] { a, b });
            Thread.Sleep(3000);
        }
    }
    public static void Process(object arg1, object arg2)
    {
        Console.WriteLine($"arg1:{arg1} arg2:{arg2}");
    }
}
public struct MyStruct
{
    public int a;
    public int b;
}
public class MyClass
{
    public int a;
    public int b;
}

Когда я запускаю свой код Process параметр метода arg2 найдено 'FatalExecutionEngineError' не может прочитать память.

Но если я изменю свой второй параметр на MyStruct лайк

    public static void Process(object arg1,MyStruct arg2)
    {
        Console.WriteLine($"arg1:{arg1} arg2:{arg2}");
    }

Работает нормально, но это не то, что я хочу.

Я думаю, что мой код IL не верен, но я не знаю, где он.

1 ответ

Решение

Вы должны позвонить OpCodes.Box на MyStruct чтобы передать его как object в качестве параметра к методу.

Вам также не нужно звонить OpCodes.Nopили. Итак, в основном ваш код должен выглядеть так:

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Box, typeof(MyStruct));
//Rest is the same
Другие вопросы по тегам