C# - Reflection.Emit : Return 被调用方法的结果
C# - Reflection.Emit : Return result of called method
在 DynamicMethod 中,我尝试调用一个方法,该方法需要对象数组 return 给定数组的长度。目前,应该从 DynamicMethod 调用的我的方法如下所示:
public static int Test(Object[] args)
{
Console.WriteLine(args.Length);
return args.Length;
}
DynamicMethod 的创建过程如下所示:
(Object数组的创建借鉴自以下)
public static DynamicMethod GetDM()
{
var returnType = typeof(int);
var paramTypes = new Type[]{typeof(string), typeof(bool)};
var method = new DynamicMethod(
"",
returnType,
paramTypes,
false
);
var il = method.GetILGenerator();
// Save parameters in an object array
il.Emit(OpCodes.Ldc_I4_S, paramTypes.Length);
il.Emit(OpCodes.Newarr, typeof(Object));
il.Emit(OpCodes.Dup);
for (int i = 0; i < paramTypes.Length; i++)
{
Type type = paramTypes[i];
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i);
if (type.IsValueType) { il.Emit(OpCodes.Box, type); }
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Dup);
}
// Call method and get the length of the array
// How do I return the result of the called method?
var callMethod = typeof(Program).GetMethod("Test", (BindingFlags)(-1));
il.Emit(OpCodes.Call, callMethod);
il.Emit(OpCodes.Ret);
return method;
}
我使用以下方法检查功能:
public static void Main(string[] args)
{
var method = GetDM();
var result = method.Invoke(null, new Object[]{"Test 1234", true});
Console.WriteLine(result); // Should be 2
}
当我 运行 main 方法时,我得到了 System.Reflection.TargetInvocationException
。有人可以帮我解决如何 return 被调用方法 return 编辑的值吗?这是一个 link 到 dotnetfiddle 以查看我的实际问题。
在 for
循环之后,您在堆栈上有两次构造的对象数组(因为 Dup
调用)。 Call
仅使用这些数组引用之一,因此在该方法结束时,堆栈上将有一个额外的数组引用。
要更正此问题,请移除第一个 Dup 并将第二个 Dup 移动到循环体的头部:
public static DynamicMethod GetDM() {
var returnType = typeof(int);
var paramTypes = new Type[]{typeof(string), typeof(bool)};
var method = new DynamicMethod(
"",
returnType,
paramTypes,
false
);
var il = method.GetILGenerator();
// Save parameters in an object array
il.Emit(OpCodes.Ldc_I4_S, paramTypes.Length);
il.Emit(OpCodes.Newarr, typeof(Object));
for (int i = 0; i < paramTypes.Length; i++)
{
Type type = paramTypes[i];
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i);
if (type.IsValueType) { il.Emit(OpCodes.Box, type); }
il.Emit(OpCodes.Stelem_Ref);
}
// Call method and get the length of the array
// How do I return the result of the called method?
var callMethod = typeof(Program).GetMethod("Test", (BindingFlags)(-1));
il.Emit(OpCodes.Call, callMethod);
il.Emit(OpCodes.Ret);
return method;
}
在 DynamicMethod 中,我尝试调用一个方法,该方法需要对象数组 return 给定数组的长度。目前,应该从 DynamicMethod 调用的我的方法如下所示:
public static int Test(Object[] args)
{
Console.WriteLine(args.Length);
return args.Length;
}
DynamicMethod 的创建过程如下所示:
(Object数组的创建借鉴自以下
public static DynamicMethod GetDM()
{
var returnType = typeof(int);
var paramTypes = new Type[]{typeof(string), typeof(bool)};
var method = new DynamicMethod(
"",
returnType,
paramTypes,
false
);
var il = method.GetILGenerator();
// Save parameters in an object array
il.Emit(OpCodes.Ldc_I4_S, paramTypes.Length);
il.Emit(OpCodes.Newarr, typeof(Object));
il.Emit(OpCodes.Dup);
for (int i = 0; i < paramTypes.Length; i++)
{
Type type = paramTypes[i];
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i);
if (type.IsValueType) { il.Emit(OpCodes.Box, type); }
il.Emit(OpCodes.Stelem_Ref);
il.Emit(OpCodes.Dup);
}
// Call method and get the length of the array
// How do I return the result of the called method?
var callMethod = typeof(Program).GetMethod("Test", (BindingFlags)(-1));
il.Emit(OpCodes.Call, callMethod);
il.Emit(OpCodes.Ret);
return method;
}
我使用以下方法检查功能:
public static void Main(string[] args)
{
var method = GetDM();
var result = method.Invoke(null, new Object[]{"Test 1234", true});
Console.WriteLine(result); // Should be 2
}
当我 运行 main 方法时,我得到了 System.Reflection.TargetInvocationException
。有人可以帮我解决如何 return 被调用方法 return 编辑的值吗?这是一个 link 到 dotnetfiddle 以查看我的实际问题。
在 for
循环之后,您在堆栈上有两次构造的对象数组(因为 Dup
调用)。 Call
仅使用这些数组引用之一,因此在该方法结束时,堆栈上将有一个额外的数组引用。
要更正此问题,请移除第一个 Dup 并将第二个 Dup 移动到循环体的头部:
public static DynamicMethod GetDM() {
var returnType = typeof(int);
var paramTypes = new Type[]{typeof(string), typeof(bool)};
var method = new DynamicMethod(
"",
returnType,
paramTypes,
false
);
var il = method.GetILGenerator();
// Save parameters in an object array
il.Emit(OpCodes.Ldc_I4_S, paramTypes.Length);
il.Emit(OpCodes.Newarr, typeof(Object));
for (int i = 0; i < paramTypes.Length; i++)
{
Type type = paramTypes[i];
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldc_I4, i);
il.Emit(OpCodes.Ldarg, i);
if (type.IsValueType) { il.Emit(OpCodes.Box, type); }
il.Emit(OpCodes.Stelem_Ref);
}
// Call method and get the length of the array
// How do I return the result of the called method?
var callMethod = typeof(Program).GetMethod("Test", (BindingFlags)(-1));
il.Emit(OpCodes.Call, callMethod);
il.Emit(OpCodes.Ret);
return method;
}