IL的Emit用于调用委托实例?

编程入门 行业动态 更新时间:2024-10-28 05:12:58
本文介绍了IL的Emit用于调用委托实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

基本上,我接受事件名称作为一个字符串,以获得 EventInfo 。然后,我发现使用反射事件处理程序的类型和事件参数类型,创建类型( myEventHandler )的新代表,并与该事件挂钩起来。当过 myEventHandler 被调用,我需要向下转换和传递参数给处理程序。

Basically, I'm accepting an event name as a string, to get the EventInfo. Then, I'm discovering the event handler type and event argument type using reflection, creating a new delegate of that type (myEventHandler), and hooking it up with the event. When ever myEventHandler is invoked, I need to downcast and pass the arguments to the handler.

我的code是如下。该处理程序需要通过 myEventHandler 来调用,D被调用时直到永远。我需要有一些反射发出code那里有我把???。有什么想法?

My code is as below. The 'handler' needs to be invoked via myEventHandler, when ever 'd' is invoked. I need to have some Reflection emit code there where I put ???. Any thoughts?

EventHandler handler = delegate(object sender, EventArgs eventArgs) { //something will happen here }; Type[] typeArgs = { typeof(object), derivedEventArgsType }; DynamicMethod myEventHandler = new DynamicMethod("", typeof(void), typeArgs); var ilgen = myEventHandler.GetILGenerator(); //What should be the IL code here to //cast derviedEventArgs to EventArgs and //invoke the 'handler' above?????? ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Ret); Delegate d = dynamic.CreateDelegate(derviedEventHandlerType); //addMethod is the add MethodInfo for an Event addMethod.Invoke(target, new object[] { d });

编辑:基于通过反射观察

反射器产生的code对于手动codeD的情况是

The reflector generated code for a manually coded scenario is

.method public hidebysig instance void <Main>b__1(object sender, class ConsoleApplication2.MyEventArgs e) cil managed { .maxstack 8 L_0000: nop L_0001: ldarg.0 L_0002: ldfld class [mscorlib]System.EventHandler ConsoleApplication2.Program/<>c__DisplayClass3::handler L_0007: ldarg.1 L_0008: ldarg.2 L_0009: callvirt instance void [mscorlib]System.EventHandler::Invoke(object, class [mscorlib]System.EventArgs) L_000e: nop L_000f: ret }

这是我试过的基础上。

And this is what I tried based on that.

ilgen.Emit(OpCodes.Nop); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldfld,eh.GetType().GetField("handler")); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); ilgen.EmitCall(OpCodes.Callvirt,eh.handler.Method, new Type[]{ typeof(object), typeof(EventArgs) }); ilgen.Emit(OpCodes.Nop); ilgen.Emit(OpCodes.Ret);

但是,这是造成运行时错误:

调用约定必须是可变参数

'Calling convention must be varargs'

也许我失去了一些东西,需要有一个更美好的期待成IL。

Probably I'm missing something, need to have a better look into IL.

推荐答案

原来我是大大过于复杂的事情!巴里·凯利是对的:

It turns out I was vastly over-complicating things! Barry Kelly had the right idea:

static T CastDelegate<T>(Delegate src) where T : class { return (T)(object)Delegate.CreateDelegate( typeof(T), src.Target, src.Method, true); // throw on fail }

这是适合我的测试用例。

That works for my test cases.

更多推荐

IL的Emit用于调用委托实例?

本文发布于:2023-11-17 03:39:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1608688.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实例   IL   Emit

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!