首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过CIL DynamicMethod调用方法

通过CIL DynamicMethod调用方法
EN

Stack Overflow用户
提问于 2020-10-13 08:52:28
回答 1查看 94关注 0票数 1

我试图通过il调用一个方法,虽然指令似乎是正确的,但我得到了一个System.Security.VerificationException:“操作可能破坏运行时的稳定。”

这个电话看起来像var a = Configuration.JsonHandler.Deserialize(typeof(Dictionary<string, object>), "{}")

使用ILDASM可以生成以下指令:

代码语言:javascript
复制
.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

动态方法/il的c#代码

代码语言:javascript
复制
        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可视化器,我可以看到上面的代码生成的完全相同。

代码语言:javascript
复制
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      

任何人都能指出我做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-13 10:45:57

Operation could destabilize the runtime.错误是由您试图获取MethodInfo的错误类型造成的。您必须使用接口类型,而不是实现。

如下所示:

代码语言:javascript
复制
var deserializeMethod = typeof(IJsonHandler).GetMethod("Deserialize");

我还假设您希望返回Deserialize()的结果,所以应该在动态方法声明中这样说:

代码语言:javascript
复制
var dynamicMethod = new DynamicMethod("DynamicMethod", typeof(object), null, true);

并相应地更改委托创建:

代码语言:javascript
复制
var func = (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));

在这种情况下,您应该在Pop之前删除Ret指令。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64331849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档