C#中调用动态方法时如何传递Struct参数?
How to pass Struct parameter when a Dynamic Method Invoke in 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 代码不正确,但我不知道它在哪里。
您必须在 MyStruct
上调用 OpCodes.Box
才能将其作为 object
作为参数传递给方法。
您也不需要调用 OpCodes.Nop
。
所以基本上你的代码应该是这样的→
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Box, typeof(MyStruct));
//Rest is the same
我在动态方法中传递结构参数时遇到问题。 这是我的代码:
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 代码不正确,但我不知道它在哪里。
您必须在 MyStruct
上调用 OpCodes.Box
才能将其作为 object
作为参数传递给方法。
您也不需要调用 OpCodes.Nop
。
所以基本上你的代码应该是这样的→
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Box, typeof(MyStruct));
//Rest is the same