反射在评估堆栈上发出推送和附加参数
reflection emit push and additional argument on evaluation stack
我有为函数创建代理的工作代码:
// For this controller, I only want a Get method to server Get request
MethodBuilder myGetMethod =
tb.DefineMethod("Get",
MethodAttributes.Public,
typeof(String), new Type[] { typeof(String) });
// Define parameters
myGetMethod.DefineParameter(
position: 1, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
attributes: ParameterAttributes.None,
strParamName: "stringParam"
);
ILGenerator myMethodIL = myGetMethod.GetILGenerator();
Func<string, string> method = (v) => "Poop";
myMethodIL.Emit(OpCodes.Jmp, method.Method);
myMethodIL.Emit(OpCodes.Ret);
我想扩展函数以接受依赖项。例如
Func<string, string, string> method = (v, s) => v + s + "Poop";
myMethodIL.Emit(OpCodes.Ldstr, "Hi");
myMethodIL.Emit(OpCodes.Jmp, method.Method);
myMethodIL.Emit(OpCodes.Ret);
我正在尝试将加载的字符串推送到评估堆栈上,在此之前评估堆栈已经加载了输入参数,因此在调用跳转时参数对齐良好。但是现在我的 func 需要接受一个额外的参数,我需要将加载的字符串压入堆栈。但是,当我 运行 出现此错误时:
Common Language Runtime detected an invalid program.
如何在调用我的代理之前在计算堆栈上弹出一个附加参数?
事实证明,跳转语句仅在转发相同参数时才有效,而不是弄清楚如何编写正确的 IL 我现在只是从 DI 容器中注入我需要的东西。
public static Type CompileResultType(string typeSignature, Dictionary<string, string> propDic)
{
TypeBuilder tb = GetTypeBuilder(typeSignature);
tb.SetParent(typeof(DynamicControllerBase));
ConstructorBuilder ctor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
foreach (var item in propDic)
{
CreateProperty(tb, item.Key, Type.GetType(item.Value));
}
// For this controller, I only want a Get method to server Get request
MethodBuilder myGetMethod =
tb.DefineMethod("Get",
MethodAttributes.Public,
typeof(String), new Type[] { typeof(Test), typeof(String) });
// Define parameters
var parameterBuilder = myGetMethod.DefineParameter(
position: 1, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
attributes: ParameterAttributes.None,
strParamName: "test"
);
var attributeBuilder
= new CustomAttributeBuilder(typeof(FromServicesAttribute).GetConstructor(Type.EmptyTypes), Type.EmptyTypes);
parameterBuilder.SetCustomAttribute(attributeBuilder);
// Define parameters
myGetMethod.DefineParameter(
position: 2, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
attributes: ParameterAttributes.None,
strParamName: "stringParam"
);
// Generate IL for method.
ILGenerator myMethodIL = myGetMethod.GetILGenerator();
Func<string, string> method = (v) => "Poop";
Func<Test, string, string> method1 = (v, s) => v.Name + s;
myMethodIL.Emit(OpCodes.Jmp, method1.Method);
myMethodIL.Emit(OpCodes.Ret);
return tb.CreateType();
}
我有为函数创建代理的工作代码:
// For this controller, I only want a Get method to server Get request
MethodBuilder myGetMethod =
tb.DefineMethod("Get",
MethodAttributes.Public,
typeof(String), new Type[] { typeof(String) });
// Define parameters
myGetMethod.DefineParameter(
position: 1, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
attributes: ParameterAttributes.None,
strParamName: "stringParam"
);
ILGenerator myMethodIL = myGetMethod.GetILGenerator();
Func<string, string> method = (v) => "Poop";
myMethodIL.Emit(OpCodes.Jmp, method.Method);
myMethodIL.Emit(OpCodes.Ret);
我想扩展函数以接受依赖项。例如
Func<string, string, string> method = (v, s) => v + s + "Poop";
myMethodIL.Emit(OpCodes.Ldstr, "Hi");
myMethodIL.Emit(OpCodes.Jmp, method.Method);
myMethodIL.Emit(OpCodes.Ret);
我正在尝试将加载的字符串推送到评估堆栈上,在此之前评估堆栈已经加载了输入参数,因此在调用跳转时参数对齐良好。但是现在我的 func 需要接受一个额外的参数,我需要将加载的字符串压入堆栈。但是,当我 运行 出现此错误时:
Common Language Runtime detected an invalid program.
如何在调用我的代理之前在计算堆栈上弹出一个附加参数?
事实证明,跳转语句仅在转发相同参数时才有效,而不是弄清楚如何编写正确的 IL 我现在只是从 DI 容器中注入我需要的东西。
public static Type CompileResultType(string typeSignature, Dictionary<string, string> propDic)
{
TypeBuilder tb = GetTypeBuilder(typeSignature);
tb.SetParent(typeof(DynamicControllerBase));
ConstructorBuilder ctor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
foreach (var item in propDic)
{
CreateProperty(tb, item.Key, Type.GetType(item.Value));
}
// For this controller, I only want a Get method to server Get request
MethodBuilder myGetMethod =
tb.DefineMethod("Get",
MethodAttributes.Public,
typeof(String), new Type[] { typeof(Test), typeof(String) });
// Define parameters
var parameterBuilder = myGetMethod.DefineParameter(
position: 1, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
attributes: ParameterAttributes.None,
strParamName: "test"
);
var attributeBuilder
= new CustomAttributeBuilder(typeof(FromServicesAttribute).GetConstructor(Type.EmptyTypes), Type.EmptyTypes);
parameterBuilder.SetCustomAttribute(attributeBuilder);
// Define parameters
myGetMethod.DefineParameter(
position: 2, // 0 is the return value, 1 is the 1st param, 2 is 2nd, etc.
attributes: ParameterAttributes.None,
strParamName: "stringParam"
);
// Generate IL for method.
ILGenerator myMethodIL = myGetMethod.GetILGenerator();
Func<string, string> method = (v) => "Poop";
Func<Test, string, string> method1 = (v, s) => v.Name + s;
myMethodIL.Emit(OpCodes.Jmp, method1.Method);
myMethodIL.Emit(OpCodes.Ret);
return tb.CreateType();
}