通过 CIL DynamicMethod 调用方法
Calling a method through CIL DynamicMethod
我正在尝试通过 il 调用一个方法,尽管说明似乎是正确的,但我得到了 System.Security.VerificationException:'Operation could destabilize the runtime.'
电话看起来像 var a = Configuration.JsonHandler.Deserialize(typeof(Dictionary<string, object>), "{}")
使用 ILDASM 这会生成以下指令:
.method private hidebysig static void Run() cil managed
{
// Code size 27 (0x1b)
.maxstack 8
IL_0000: call class IJsonHandler Configuration::get_JsonHandler()
IL_0005: ldtoken class [mscorlib]System.Collections.Generic.Dictionary`2<string,object>
IL_000a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000f: ldstr "{}"
IL_0014: callvirt instance object IJsonHandler::Deserialize(class [mscorlib]System.Type,string)
IL_0019: pop
IL_001a: ret
} // end of method Program::Run
动态的c#代码method/il
var jHandlerGetter = typeof(Configuration).GetProperties().Where(p => p.PropertyType == typeof(IJsonHandler)).Select(p => p.GetGetMethod()).First();
var deserializeMethod = Configuration.JsonHandler.GetType().GetMethod("Deserialize");
var dynamicMethod = new DynamicMethod("DynamicMethod", null, null, true);
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Call, jHandlerGetter);
il.Emit(OpCodes.Ldtoken, typeof(Dictionary<string, string>));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
il.Emit(OpCodes.Ldstr, "{}");
il.Emit(OpCodes.Callvirt, deserializeMethod);
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ret);
var action = (Action)dynamicMethod.CreateDelegate(typeof(Action));
action();
使用 il 可视化工具,我可以看到上面生成的完全相同的指令。
IL_0000: call IJsonHandler get_JsonHandler()/Configuration
IL_0005: ldtoken System.Collections.Generic.Dictionary`2[System.String,System.String]/
IL_000a: call System.Type GetTypeFromHandle(System.RuntimeTypeHandle)/System.Type
IL_000f: ldstr "{}"
IL_0014: callvirt System.Object Deserialize(System.Type, System.String)/JHandler
IL_0019: pop
IL_001a: ret
谁能指出我做错了什么??
Operation could destabilize the runtime.
错误是由于您尝试获取 MethodInfo 的类型错误造成的。您必须使用接口类型而不是实现。
像这样:
var deserializeMethod = typeof(IJsonHandler).GetMethod("Deserialize");
我还假设你想要 return 与 Deserialize()
的结果,所以你应该在动态方法声明中这样说:
var dynamicMethod = new DynamicMethod("DynamicMethod", typeof(object), null, true);
并相应地更改委托创建:
var func = (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));
在这种情况下,您应该删除 Ret
之前的 Pop
指令。
我正在尝试通过 il 调用一个方法,尽管说明似乎是正确的,但我得到了 System.Security.VerificationException:'Operation could destabilize the runtime.'
电话看起来像 var a = Configuration.JsonHandler.Deserialize(typeof(Dictionary<string, object>), "{}")
使用 ILDASM 这会生成以下指令:
.method private hidebysig static void Run() cil managed
{
// Code size 27 (0x1b)
.maxstack 8
IL_0000: call class IJsonHandler Configuration::get_JsonHandler()
IL_0005: ldtoken class [mscorlib]System.Collections.Generic.Dictionary`2<string,object>
IL_000a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000f: ldstr "{}"
IL_0014: callvirt instance object IJsonHandler::Deserialize(class [mscorlib]System.Type,string)
IL_0019: pop
IL_001a: ret
} // end of method Program::Run
动态的c#代码method/il
var jHandlerGetter = typeof(Configuration).GetProperties().Where(p => p.PropertyType == typeof(IJsonHandler)).Select(p => p.GetGetMethod()).First();
var deserializeMethod = Configuration.JsonHandler.GetType().GetMethod("Deserialize");
var dynamicMethod = new DynamicMethod("DynamicMethod", null, null, true);
var il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Call, jHandlerGetter);
il.Emit(OpCodes.Ldtoken, typeof(Dictionary<string, string>));
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
il.Emit(OpCodes.Ldstr, "{}");
il.Emit(OpCodes.Callvirt, deserializeMethod);
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ret);
var action = (Action)dynamicMethod.CreateDelegate(typeof(Action));
action();
使用 il 可视化工具,我可以看到上面生成的完全相同的指令。
IL_0000: call IJsonHandler get_JsonHandler()/Configuration
IL_0005: ldtoken System.Collections.Generic.Dictionary`2[System.String,System.String]/
IL_000a: call System.Type GetTypeFromHandle(System.RuntimeTypeHandle)/System.Type
IL_000f: ldstr "{}"
IL_0014: callvirt System.Object Deserialize(System.Type, System.String)/JHandler
IL_0019: pop
IL_001a: ret
谁能指出我做错了什么??
Operation could destabilize the runtime.
错误是由于您尝试获取 MethodInfo 的类型错误造成的。您必须使用接口类型而不是实现。
像这样:
var deserializeMethod = typeof(IJsonHandler).GetMethod("Deserialize");
我还假设你想要 return 与 Deserialize()
的结果,所以你应该在动态方法声明中这样说:
var dynamicMethod = new DynamicMethod("DynamicMethod", typeof(object), null, true);
并相应地更改委托创建:
var func = (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));
在这种情况下,您应该删除 Ret
之前的 Pop
指令。