|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
A little help with Reflection.Emit and TypeBuilder.GetMethod...Brief description: I am creating a dynamic assembly. I have a class with has some properties. These properties have data types of classes which exist in the dynamic assembly. The class has a dynamic method in which I would like to reference the properties within the class. My problem is explained at the very end... I'll present the code as it looks if typed in the IDE (both VB and IL), and then below I'll present my dynamic code gen function (in VB): Excerpt VB Code: Private oSignalDetections As SignalDetectionCollection = New SignalDetectionCollection Private oSupportBlock As SupportBlock151 = New SupportBlock151 #Region " Heavy Lifting " Public Overrides Sub AssignBlocks(ByVal tBlocks As BlockCollection) SetBlockBasics(tBlocks(0), Me.AdminBlock) SetBlockBasics(tBlocks(1), Me.SignalDetections) SetBlockBasics(tBlocks(2), Me.SupportBlock) End Sub #End Region Translated to IL via ILDASM: ..method public strict virtual instance void AssignBlocks(class RCCAlertParser.BlockCollection tBlocks) cil managed { // Code size 111 (0x6f) .maxstack 3 .locals init ([0] class RCCAlertParser.IBlock _Vb_t_ref_0) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldarg.1 IL_0003: ldc.i4.0 IL_0004: callvirt instance class RCCAlertParser.Block RCCAlertParser.BlockCollection::get_Item(int32) IL_0009: ldarg.0 IL_000a: callvirt instance class RCCAlertParser.AdministrativeBlock RCCAlertParser.Alert::get_AdminBlock() IL_000f: stloc.0 IL_0010: ldloca.s _Vb_t_ref_0 IL_0012: callvirt instance void RCCAlertParser.Alert::SetBlockBasics(class RCCAlertParser.IBlock, class RCCAlertParser.IBlock&) IL_0017: nop IL_0018: ldarg.0 IL_0019: ldloc.0 IL_001a: castclass RCCAlertParser.AdministrativeBlock IL_001f: callvirt instance void RCCAlertParser.Alert::set_AdminBlock(class RCCAlertParser.AdministrativeBlock) IL_0024: nop IL_0025: ldarg.0 IL_0026: ldarg.1 IL_0027: ldc.i4.1 IL_0028: callvirt instance class RCCAlertParser.Block RCCAlertParser.BlockCollection::get_Item(int32) IL_002d: ldarg.0 IL_002e: callvirt instance class RCCAlertParser.SignalDetectionCollection RCCAlertParser.Alert151::get_SignalDetections() IL_0033: stloc.0 IL_0034: ldloca.s _Vb_t_ref_0 IL_0036: callvirt instance void RCCAlertParser.Alert::SetBlockBasics(class RCCAlertParser.IBlock, class RCCAlertParser.IBlock&) IL_003b: nop IL_003c: ldarg.0 IL_003d: ldloc.0 IL_003e: castclass RCCAlertParser.SignalDetectionCollection IL_0043: callvirt instance void RCCAlertParser.Alert151::set_SignalDetections(class RCCAlertParser.SignalDetectionCollection) IL_0048: nop IL_0049: ldarg.0 IL_004a: ldarg.1 IL_004b: ldc.i4.2 IL_004c: callvirt instance class RCCAlertParser.Block RCCAlertParser.BlockCollection::get_Item(int32) IL_0051: ldarg.0 IL_0052: callvirt instance class RCCAlertParser.SupportBlock151 RCCAlertParser.Alert151::get_SupportBlock() IL_0057: stloc.0 IL_0058: ldloca.s _Vb_t_ref_0 IL_005a: callvirt instance void RCCAlertParser.Alert::SetBlockBasics(class RCCAlertParser.IBlock, class RCCAlertParser.IBlock&) IL_005f: nop IL_0060: ldarg.0 IL_0061: ldloc.0 IL_0062: castclass RCCAlertParser.SupportBlock151 IL_0067: callvirt instance void RCCAlertParser.Alert151::set_SupportBlock(class RCCAlertParser.SupportBlock151) IL_006c: nop IL_006d: nop IL_006e: ret } // end of method Alert151::AssignBlocks DYNAMIC CODE GEN: Private Sub BuildAssignBlocksPart(ByRef tTypeBuilder As TypeBuilder, ByRef tILGenerator As ILGenerator, ByVal tBlockIndex As Int32, ByVal tPropertyType As Type, ByVal tPropertyName As String) Dim tBaseMethod As MethodInfo = Nothing With tILGenerator .Emit(OpCodes.Nop) .Emit(OpCodes.Ldarg_0) .Emit(OpCodes.Ldarg_1) .Emit(OpCodes.Ldc_I4, tBlockIndex) tBaseMethod = GetType(BlockCollection).GetMethod("get_Item") .Emit(OpCodes.Callvirt, tBaseMethod) .Emit(OpCodes.Ldarg_0) tBaseMethod = tTypeBuilder.GetMethod("get_" & tPropertyName) .Emit(OpCodes.Callvirt, tBaseMethod) .Emit(OpCodes.Stloc_0) .Emit(OpCodes.Ldloca_S, 0) tBaseMethod = tTypeBuilder.GetMethod("SetBlockBasics") .Emit(OpCodes.Callvirt, tBaseMethod) .Emit(OpCodes.Nop) .Emit(OpCodes.Ldarg_0) .Emit(OpCodes.Ldloc_0) .Emit(OpCodes.Castclass, tPropertyType) tBaseMethod = tTypeBuilder.GetMethod("set_" & tPropertyName) .Emit(OpCodes.Callvirt, tBaseMethod) End With End Sub The code above fails at: tBaseMethod = tTypeBuilder.GetMethod("get_" & tPropertyName) Note that the type represented by tTypeBuilder is dynamic (it was created earlier in the assembly building process) and is part of the same assembly that this code gen is trying to write to. The exact exception is: An unhandled exception of type 'System.NotSupportedException' occurred in mscorlib.dll Additional information: The invoked member is not supported in a dynamic module. So... how would one go about this? Thanks in advance, -Dan |
|||||||||||||||||||||||