Autor Beitrag
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 07.09.14 19:49 
Moin,

ich versuche mich gerade an IL-Code und versuche den decompilierten Code einer kleinen Test-Anwendung dynamisch in C# nachzubauen.
Soweit verstehe ich den Code auch (glaube ich zumindest), Probleme habe ich bei der Umsetzung in C# mit den Emit-Überladungen.

Die Klasse, die ich erstelle, enthält unter Anderem ein Feld mit einem Delegat-Typen.
Dieser Delegat soll nun in einer Property aufgerufen werden, der soll im Set-Accessor der angegebenen Wert prüfen.

Hier das Vorbild, nach dem ich arbeite:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
IL_0017: ldarg.0
IL_0018: ldfld class [mscorlib]System.Func`2<class ILTest.Program, bool> ILTest.Program::_MyObjectValidator
IL_001d: ldarg.1
IL_001e: callvirt instance !1 class [mscorlib]System.Func`2<class ILTest.Program, bool>::Invoke(!0)
IL_0023: stloc.0
IL_0024: ldloc.0
IL_0025: brtrue.s IL_0037


Und soweit bin ich bisher:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
propertySetAccessorIL.Emit(OpCodes.Ldarg_0);
propertySetAccessorIL.Emit(OpCodes.Ldfld, _validatorField);
propertySetAccessorIL.Emit(OpCodes.Ldarg_1);
propertySetAccessorIL.EmitCall(OpCodes.Callvirt, /* Hier weiß ich nicht weiter */new Type[] { PropertyDefinition.PropertyType, typeof(bool) });
propertySetAccessorIL.Emit(OpCodes.Stloc_0);
propertySetAccessorIL.Emit(OpCodes.Ldloc_0);
propertySetAccessorIL.Emit(OpCodes.Brtrue_S, endCheckWithValidatorLabel);


Das Feld wird auf den Auswertungsstapel geladen und wartet jetzt dort darauf, dass der Delegat aufgerufen wird.
Die Methoden Emit oder EmitCall verlangen aber beide eine MethodInfo, die mir zu dem Zeitpunkt aber noch nicht bekannt ist.
Ich habe nur die FieldInfo des Feldes und kann mir über den Wert die MethodInfo holen, aber auch nur mit einer Instanz, die ich nicht habe.

Weiß jemand, wie ich den Aufruf des Delegaten in diesem Instanz-Feld richtig darstellen kann?


Besten Dank im Vorraus :)
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 07.09.14 22:26 
Ich glaube, ich habe die Lösung gefunden:

ausblenden C#-Quelltext
1:
propertySetAccessorIL.EmitCall(OpCodes.Callvirt, _validatorType.GetMethod("Invoke"), new Type[] { PropertyDefinition.PropertyType, typeof(bool) });					

oder

ausblenden C#-Quelltext
1:
propertySetAccessorIL.Emit(OpCodes.Callvirt, _validatorType.GetMethod("Invoke"));					


Punkt ist der, dass ein Delegat an sich ja keine Methode ist, sondern ein Objekt wie jedes Andere auch.
Aufgerufen wird also nicht der Delegat, sondern die Invoke-Methode, die jeder Delegat hat und genau diese Methode will die Emit-Methode haben.

Ich konnte es bisher noch nicht testen, werde aber hier eine Info hinterlassen, sobald ich es getestet habe.