기본적으로 이벤트 이름을 문자열로 받아 들여 EventInfo
이됩니다. 그런 다음 리플렉션을 사용하여 이벤트 핸들러 유형 및 이벤트 인수 유형을 찾고 해당 유형의 새 델리게이트 (myEventHandler
)를 작성한 후 이벤트와 연결합니다. 언제 myEventHandler
호출 될 때, 나는 다운 캐스트하고 처리기에 인수를 전달해야합니다.IL Delegate 인스턴스를 호출하기위한 Emit?
내 코드는 다음과 같습니다. '핸들러'는 myEventHandler
을 통해 호출되어야하며 'd'가 호출됩니다. 나는 반사 (Reflection) 코드를 거기에 놓을 필요가있다. 이견있는 사람?
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 });
편집 : 반사경을 통해 관찰을 기준으로합니다.
반사기는 수동으로 코딩 시나리오에 대한 코드를 생성
.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
}
입니다 그리고 이것은 내가 그 기반으로 시도하는 것이다.
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에 더 나은 모습이 필요합니다.
트릭은 항상 C#에서 원하는 코드를 작성하고 reflector/ILDASM을 사용하여 IL을 봅니다. 나는 ld, castclass, 그리고 callvirt의 조합을 추측 할 것이다 –
그래도 동의했다. 나는 그 길을 택할 것이지만 어떤 반사도 생각해 냈다. 그래서 Ninjas는 빠르게 이것을 지적 할 수있다. – amazedsaint
"Handler"는 어디에 있는가? args와 관련하여? 저는 두 사람을 데려 오는 것이 고통 스러울 것이라고 생각하고 있습니다. C# 버전에서 캡처 클래스를 사용하는 것처럼 보입니다. 그러나 분당 동적 메서드는 정적이므로 아무 곳이나 밀어 넣지 않아도됩니다. –