C# MSIL 调用方法并传递一个对象[]
C# MSIL call method and pass an object[]
我想使用反射发射依赖项将 C# 中的方法转换为 MSIL 代码。
我尝试转换的方法是转换方法:
public class AClass
{
public string Transformation(string a, string b, string c)
{
return new AnotherClass().Method(new object[] { a, b, c });
}
}
public class AnotherClass
{
public string Method(params object[] objs)
{
return "AAA";
}
}
所以基本上创建一个 class 的实例并使用一个新对象调用方法函数[],该对象将处理传递给它的所有参数。
当我查看 IlSpy 时,我得到了这个:
.method public hidebysig
instance string Transformation (
string a,
string b,
string c
) cil managed
{
// Method begins at RVA 0x20d0
// Code size 34 (0x22)
.maxstack 5
.locals init (
[0] string
)
IL_0000: nop
IL_0001: newobj instance void ConsoleApp1.AnotherClass::.ctor()
IL_0006: ldc.i4.3
IL_0007: newarr [mscorlib]System.Object
IL_000c: dup
IL_000d: ldc.i4.0
IL_000e: ldarg.1
IL_000f: stelem.ref
IL_0010: dup
IL_0011: ldc.i4.1
IL_0012: ldarg.2
IL_0013: stelem.ref
IL_0014: dup
IL_0015: ldc.i4.2
IL_0016: ldarg.3
IL_0017: stelem.ref
IL_0018: call instance string ConsoleApp1.AnotherClass::Method(object[])
IL_001d: stloc.0
IL_001e: br.s IL_0020
IL_0020: ldloc.0
IL_0021: ret
} // end of method AClass::Transformation
并尝试创建一个函数来表示:
public static void CallFucntionThroughIl(ILGenerator il, Type[] parameters, MethodInfo method)
{
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Newobj, typeof(AnotherClass).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Ldc_I4, parameters.Length);
il.Emit(OpCodes.Newarr, typeof(object));
for (int i = 0; i < parameters.Length; i++)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i + 1);
il.Emit(OpCodes.Stelem_Ref);
}
il.EmitCall(OpCodes.Callvirt,
typeof(AnotherClass).GetMethod("Method").MakeGenericMethod(method.ReturnType),
new Type[] { typeof(object[]) });
il.Emit(OpCodes.Stloc_0);
var label = il.DefineLabel();
il.Emit(OpCodes.Br_S, label);
il.MarkLabel(label);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
}
但有时我不知道自己做错了什么,调试时遇到的唯一错误是:
System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'
目标只是复制 "Transformation" 函数的功能,获取所有参数并将其传递给对象[] 在参数中使用该对象[] 调用方法,return其他方法 returns.
注意:转换函数并不总是要接收3个字符串,也可以是其他对象。
挖了半天:
Nop 后缺少 DeclareLocal:
il.Emit(OpCodes.Nop);
il.DeclareLocal(typeof(object[]));
尝试分配给本地不存在的变量时可能崩溃。
il.Emit(OpCodes.Stloc_0);
我想使用反射发射依赖项将 C# 中的方法转换为 MSIL 代码。
我尝试转换的方法是转换方法:
public class AClass
{
public string Transformation(string a, string b, string c)
{
return new AnotherClass().Method(new object[] { a, b, c });
}
}
public class AnotherClass
{
public string Method(params object[] objs)
{
return "AAA";
}
}
所以基本上创建一个 class 的实例并使用一个新对象调用方法函数[],该对象将处理传递给它的所有参数。
当我查看 IlSpy 时,我得到了这个:
.method public hidebysig
instance string Transformation (
string a,
string b,
string c
) cil managed
{
// Method begins at RVA 0x20d0
// Code size 34 (0x22)
.maxstack 5
.locals init (
[0] string
)
IL_0000: nop
IL_0001: newobj instance void ConsoleApp1.AnotherClass::.ctor()
IL_0006: ldc.i4.3
IL_0007: newarr [mscorlib]System.Object
IL_000c: dup
IL_000d: ldc.i4.0
IL_000e: ldarg.1
IL_000f: stelem.ref
IL_0010: dup
IL_0011: ldc.i4.1
IL_0012: ldarg.2
IL_0013: stelem.ref
IL_0014: dup
IL_0015: ldc.i4.2
IL_0016: ldarg.3
IL_0017: stelem.ref
IL_0018: call instance string ConsoleApp1.AnotherClass::Method(object[])
IL_001d: stloc.0
IL_001e: br.s IL_0020
IL_0020: ldloc.0
IL_0021: ret
} // end of method AClass::Transformation
并尝试创建一个函数来表示:
public static void CallFucntionThroughIl(ILGenerator il, Type[] parameters, MethodInfo method)
{
il.Emit(OpCodes.Nop);
il.Emit(OpCodes.Newobj, typeof(AnotherClass).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Ldc_I4, parameters.Length);
il.Emit(OpCodes.Newarr, typeof(object));
for (int i = 0; i < parameters.Length; i++)
{
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i + 1);
il.Emit(OpCodes.Stelem_Ref);
}
il.EmitCall(OpCodes.Callvirt,
typeof(AnotherClass).GetMethod("Method").MakeGenericMethod(method.ReturnType),
new Type[] { typeof(object[]) });
il.Emit(OpCodes.Stloc_0);
var label = il.DefineLabel();
il.Emit(OpCodes.Br_S, label);
il.MarkLabel(label);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
}
但有时我不知道自己做错了什么,调试时遇到的唯一错误是: System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'
目标只是复制 "Transformation" 函数的功能,获取所有参数并将其传递给对象[] 在参数中使用该对象[] 调用方法,return其他方法 returns.
注意:转换函数并不总是要接收3个字符串,也可以是其他对象。
挖了半天:
Nop 后缺少 DeclareLocal:
il.Emit(OpCodes.Nop);
il.DeclareLocal(typeof(object[]));
尝试分配给本地不存在的变量时可能崩溃。
il.Emit(OpCodes.Stloc_0);