Temel olarak, EventInfo
almak için bir olay adını bir dize olarak kabul ediyorum. Sonra yansıma kullanarak olay işleyicisi türünü ve olay bağımsız değişken türünü keşfediyorum, bu türden yeni bir temsilci (myEventHandler
) oluşturmak ve olayla bağlantı kurmak. myEventHandler
çağrısı yapıldığında, argümanları işleyiciye indirmem ve iletmem gerekiyor.IL Temsilci örneğini çağırmak için IL Emit?
Kodum aşağıdaki gibidir. 'İşleyici', 'd' çağrısı yapıldığında myEventHandler
aracılığıyla çağrılmalıdır. Orada koyduğum bazı Yansıma yayma kodlarına sahip olmam gerekiyor ???. Düşüncesi olan var mı?
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 });
Düzenleme: Reflektör yoluyla gözlemlere dayanarak.
reflektör elle kodlanmış senaryo için kod oluşturulan
.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
}
Ve bu bunu dayanarak çalıştığı şey budur.
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);
Ama bu çalışma zamanı hatası neden oluyor:
'Calling convention must be varargs'
Muhtemelen ben eksik bir şey, IL içine iyice aramak gerekir.
Burada hile yapmak istediğiniz her zaman C# içinde istediğiniz kodu yazmak ve IL'ye bakmak için reflektör/ILDASM kullanmanız yeterlidir. Anlaşılan Ld, castclass ve callvirt –
Yep'in bir kombinasyonunu tahmin ediyorum. Bu rotayı alacağım ama herhangi bir Reflection'un, Ninjas'ı SO içinde gönderebileceğini düşündüğünüzde, bunu hızlı bir şekilde belirtebiliriz. – amazedsaint
Tekrar bakın - "işleyici" nerede oturuyor? silahlara göre? İkisini bir araya getirmek için bir acı olacağını düşünüyorum. C# versiyonu bir yakalama sınıfı kullanıyor gibi görünüyor, ama dakikadaki dinamik yönteminiz durağan, bu yüzden herhangi bir devlete hiçbir şey yapamazsınız ... –