Click here to Skip to main content
15,921,841 members
Home / Discussions / C#
   

C#

 
Questioncrystal reports - setting background image??? Pin
shw 23424-Dec-08 19:29
shw 23424-Dec-08 19:29 
Questionhow to make a windows form with an arrow [modified] Pin
Jason_Shen24-Dec-08 15:57
Jason_Shen24-Dec-08 15:57 
AnswerRe: how to make a windows form with an arrow Pin
Dragonfly_Lee24-Dec-08 16:21
Dragonfly_Lee24-Dec-08 16:21 
GeneralRe: how to make a windows form with an arrow Pin
Jason_Shen24-Dec-08 22:27
Jason_Shen24-Dec-08 22:27 
GeneralRe: how to make a windows form with an arrow Pin
Christian Graus25-Dec-08 0:14
protectorChristian Graus25-Dec-08 0:14 
GeneralRe: how to make a windows form with an arrow Pin
Dragonfly_Lee25-Dec-08 0:43
Dragonfly_Lee25-Dec-08 0:43 
GeneralRe: how to make a windows form with an arrow Pin
Jason_Shen25-Dec-08 4:50
Jason_Shen25-Dec-08 4:50 
QuestionCan't figure out where this code might be going wrong Pin
SteelIXB24-Dec-08 15:29
SteelIXB24-Dec-08 15:29 
Hi, I'm writing some code that will create some static methods for a dynamically created assembly. One method is giving me an InvalidProgramException when run.

The code that I am trying to generate, from C# is:

//The following code should be generated by this.
//The field 'types' is a static Dictionary<string,>
//The method should search the dictionary for a value that is equal to 'type' and return the key
//
//        public static bool TryGetName(Type type, bool asCompiled, out string name)
//        {
//            foreach (var pair in types)
//            {
//                if (pair.Value == type)
//                {
//                    name = pair.Key;
//                    if (asCompiled) name = name.Replace("-", "::");
//                    return true;
//                }
//            }
//            name = null;
//            return false;
//        }
//


A simple method that will take a Type, a bool and return true if it finds a string that is paired with that Type.

The code to generate this is:

mb = typeBuilder.DefineMethod("TryGetName",
                              MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
                              typeof(bool), new[] { typeof(Type), typeof(bool), typeof(string).MakeByRefType() });
mb.DefineParameter(1, ParameterAttributes.None, "type");
mb.DefineParameter(2, ParameterAttributes.None, "asCompiled");
mb.DefineParameter(3, ParameterAttributes.Out, "name");

ILGenerator tryGetNameIL = mb.GetILGenerator();
LocalBuilder tryGetName_pairLocal = tryGetNameIL.DeclareLocal(typeof(KeyValuePair<string,>));
LocalBuilder tryGetName_enumLocal = tryGetNameIL.DeclareLocal(typeof (Dictionary<string,>.Enumerator));
LocalBuilder tryGetName_resLocal = tryGetNameIL.DeclareLocal(typeof (bool));

Label tryGetName_endLoopLabel = tryGetNameIL.DefineLabel();
Label tryGetName_startLoopLabel = tryGetNameIL.DefineLabel();
Label tryGetName_endStringReplaceLabel = tryGetNameIL.DefineLabel();
Label tryGetName_endOfMethod = tryGetNameIL.DefineLabel();

//Load the types field, and call the GetEnumerator method for it, store this in enumLocal
tryGetNameIL.Emit(OpCodes.Ldfld, typesFieldBuilder);
tryGetNameIL.EmitCall(OpCodes.Callvirt, typesFieldBuilder.FieldType.GetMethod("GetEnumerator", Type.EmptyTypes), null);
tryGetNameIL.Emit(OpCodes.Stloc, tryGetName_enumLocal);
//---

//Begin the exception block
tryGetNameIL.BeginExceptionBlock();
//Jump to the end of the loop
tryGetNameIL.Emit(OpCodes.Br_S, tryGetName_endLoopLabel);

//startLoop:
tryGetNameIL.MarkLabel(tryGetName_startLoopLabel);
//Load enum, and get the Current property value, storing as pair
tryGetNameIL.Emit(OpCodes.Ldloca_S, tryGetName_enumLocal);
tryGetNameIL.EmitCall(OpCodes.Call, tryGetName_enumLocal.LocalType.GetProperty("Current").GetGetMethod(), null);
tryGetNameIL.Emit(OpCodes.Stloc, tryGetName_pairLocal);
//---
//Load the pair local, get the Value property value
//get the first argument
//test if equal
//if not, go to endLoop
tryGetNameIL.Emit(OpCodes.Ldloca_S, tryGetName_pairLocal);
tryGetNameIL.EmitCall(OpCodes.Call, tryGetName_pairLocal.LocalType.GetProperty("Value").GetGetMethod(), null);
tryGetNameIL.Emit(OpCodes.Ldarg_0);
tryGetNameIL.Emit(OpCodes.Ceq);
tryGetNameIL.Emit(OpCodes.Brfalse_S, tryGetName_endLoopLabel);
//---
//load argument 2, load the pair local
//get the value for Key on the pair
//store the returned value at the address at arg 2
tryGetNameIL.Emit(OpCodes.Ldarg_2); //load the out arg address onto the stack
tryGetNameIL.Emit(OpCodes.Ldloca_S, tryGetName_pairLocal);
tryGetNameIL.EmitCall(OpCodes.Call, tryGetName_pairLocal.LocalType.GetProperty("Key").GetGetMethod(), null);
tryGetNameIL.Emit(OpCodes.Stind_Ref); //store the name at the address on the stack (out arg)
//---
//load argument 1, the asCompiled bool
//jump to endStringReplace if it is false
tryGetNameIL.Emit(OpCodes.Ldarg_1); //load the asCompiled bool
tryGetNameIL.Emit(OpCodes.Brfalse_S, tryGetName_endStringReplaceLabel);

//string replace code
//load address stored in arg 2
//duplicate this
//replace the address loaded with object reference at address
//load string "-"
//load string "::"
//call the method Replace on the string, giving "-" and "::" as arguments
//store the reference of the returned string at the address given by
// the first loading of address at arg 2
tryGetNameIL.Emit(OpCodes.Ldarg_2);
tryGetNameIL.Emit(OpCodes.Dup);
tryGetNameIL.Emit(OpCodes.Ldind_Ref);
tryGetNameIL.Emit(OpCodes.Ldstr, "-");
tryGetNameIL.Emit(OpCodes.Ldstr, "::");
tryGetNameIL.EmitCall(OpCodes.Callvirt, typeof(string).GetMethod("Replace", new [] {typeof(string), typeof(string)}), null);
tryGetNameIL.Emit(OpCodes.Stind_Ref);
//--- end string replace code

//endStringReplace:
//load true
//store in res
//leave, to endOfMethod label
tryGetNameIL.MarkLabel(tryGetName_endStringReplaceLabel);
tryGetNameIL.Emit(OpCodes.Ldc_I4_1); // load true onto stack
tryGetNameIL.Emit(OpCodes.Stloc, tryGetName_resLocal);
tryGetNameIL.Emit(OpCodes.Leave_S, tryGetName_endOfMethod); //go to end of method

//endLoop:
tryGetNameIL.MarkLabel(tryGetName_endLoopLabel);
//Load local enum, call the MoveNext method, and go to startLoop if true
tryGetNameIL.Emit(OpCodes.Ldloca_S, tryGetName_enumLocal);
tryGetNameIL.EmitCall(OpCodes.Call, tryGetName_enumLocal.LocalType.GetMethod("MoveNext"), null);
tryGetNameIL.Emit(OpCodes.Brtrue_S, tryGetName_startLoopLabel);

//begin the finally block (ending the try block, with a Leave to
// the end of the finally block)
tryGetNameIL.BeginFinallyBlock();
//load the enum
//constrain the type to the enum
//call the dispose method
tryGetNameIL.Emit(OpCodes.Ldloca_S, tryGetName_enumLocal);
tryGetNameIL.Emit(OpCodes.Constrained, tryGetName_enumLocal.LocalType);
tryGetNameIL.EmitCall(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"), null);

tryGetNameIL.EndExceptionBlock();

//load address at argument 2
//load null
//store null at the address given
//load 0
//store this into res
tryGetNameIL.Emit(OpCodes.Ldarg_2);
tryGetNameIL.Emit(OpCodes.Ldnull);
tryGetNameIL.Emit(OpCodes.Stind_Ref);
tryGetNameIL.Emit(OpCodes.Ldc_I4_0);
tryGetNameIL.Emit(OpCodes.Stloc, tryGetName_resLocal);
//---

//endOfMethod:
//load res
//return
tryGetNameIL.MarkLabel(tryGetName_endOfMethod);
tryGetNameIL.Emit(OpCodes.Ldloc, tryGetName_resLocal);
tryGetNameIL.Emit(OpCodes.Ret);


And this, when run, creates the following IL:

.method public hidebysig static bool  TryGetName(class [mscorlib]System.Type 'type',
                                                 bool asCompiled,
                                                 [out] string& name) cil managed
{
  // Code size       103 (0x67)
  .maxstack  9
  .locals init (valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2<string,class> V_0,
           valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator<string,class> V_1,
           bool V_2)
  IL_0000:  ldfld      class [mscorlib]System.Collections.Generic.Dictionary`2<string,class> BlueprintSchema.BlueprintNameMapping::types
  IL_0005:  callvirt   instance valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator class [mscorlib]System.Collections.Generic.Dictionary`2<string,class>::GetEnumerator()
  IL_000a:  stloc.1
  .try
  {
    IL_000b:  br.s       IL_0044
    IL_000d:  ldloca.s   V_1
    IL_000f:  call       instance valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2 valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator<string,class>::get_Current()
    IL_0014:  stloc.0
    IL_0015:  ldloca.s   V_0
    IL_0017:  call       instance !1 valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2<string,class>::get_Value()
    IL_001c:  ldarg.0
    IL_001d:  ceq
    IL_001f:  brfalse.s  IL_0044
    IL_0021:  ldarg.2
    IL_0022:  ldloca.s   V_0
    IL_0024:  call       instance !0 valuetype [mscorlib]System.Collections.Generic.KeyValuePair`2<string,class>::get_Key()
    IL_0029:  stind.ref
    IL_002a:  ldarg.1
    IL_002b:  brfalse.s  IL_0040
    IL_002d:  ldarg.2
    IL_002e:  dup
    IL_002f:  ldind.ref
    IL_0030:  ldstr      "-"
    IL_0035:  ldstr      "::"
    IL_003a:  callvirt   instance string [mscorlib]System.String::Replace(string,
                                                                          string)
    IL_003f:  stind.ref
    IL_0040:  ldc.i4.1
    IL_0041:  stloc.2
    IL_0042:  leave.s    IL_0065
    IL_0044:  ldloca.s   V_1
    IL_0046:  call       instance bool valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator<string,class>::MoveNext()
    IL_004b:  brtrue.s   IL_000d
    IL_004d:  leave      IL_0060
  }  // end .try
  finally
  {
    IL_0052:  ldloca.s   V_1
    IL_0054:  constrained. valuetype [mscorlib]System.Collections.Generic.Dictionary`2/Enumerator<string,class>
    IL_005a:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_005f:  endfinally
  }  // end handler
  IL_0060:  ldarg.2
  IL_0061:  ldnull
  IL_0062:  stind.ref
  IL_0063:  ldc.i4.0
  IL_0064:  stloc.2
  IL_0065:  ldloc.2
  IL_0066:  ret
} // end of method BlueprintNameMapping::TryGetName


When run (e.g. calling BlueprintNameMapping.TryGetValue(typeof(Blueprints.cEngineBlueprint), true, out name); where Blueprint.cEngineBlueprint is some class not related to this), I simply get an InvalidProgramException with absolutely no clue as to where the error occured. I have read this occurs when IL is converted to native code. I have narrowed the problem down up to this method and cannot work out where it could be going wrong.

Thanks,
Ben
QuestionHow to add IP address to DNS server? Pin
s196675m24-Dec-08 12:13
s196675m24-Dec-08 12:13 
AnswerRe: How to add IP address to DNS server? Pin
Dragonfly_Lee24-Dec-08 16:17
Dragonfly_Lee24-Dec-08 16:17 
QuestionUsing collection with Designer/Editor Pin
kanchoette24-Dec-08 8:39
kanchoette24-Dec-08 8:39 
AnswerRe: Using collection with Designer/Editor Pin
Not Active24-Dec-08 9:55
mentorNot Active24-Dec-08 9:55 
GeneralRe: Using collection with Designer/Editor Pin
kanchoette25-Dec-08 1:45
kanchoette25-Dec-08 1:45 
QuestionHow Do I Run A Command Prompt Command? Pin
That Asian Guy24-Dec-08 7:10
That Asian Guy24-Dec-08 7:10 
AnswerRe: How Do I Run A Command Prompt Command? Pin
User 665824-Dec-08 7:14
User 665824-Dec-08 7:14 
GeneralRe: How Do I Run A Command Prompt Command? Pin
That Asian Guy24-Dec-08 7:19
That Asian Guy24-Dec-08 7:19 
GeneralRe: How Do I Run A Command Prompt Command? Pin
User 665824-Dec-08 7:21
User 665824-Dec-08 7:21 
GeneralRe: How Do I Run A Command Prompt Command? Pin
Colin Angus Mackay24-Dec-08 7:24
Colin Angus Mackay24-Dec-08 7:24 
GeneralRe: How Do I Run A Command Prompt Command? Pin
That Asian Guy24-Dec-08 7:25
That Asian Guy24-Dec-08 7:25 
GeneralRe: How Do I Run A Command Prompt Command? Pin
Dave Kreskowiak24-Dec-08 9:02
mveDave Kreskowiak24-Dec-08 9:02 
QuestionRemotely Turn off computer monitor Pin
balu1234524-Dec-08 6:57
balu1234524-Dec-08 6:57 
AnswerRe: Remotely Turn off computer monitor Pin
#realJSOP24-Dec-08 7:17
professional#realJSOP24-Dec-08 7:17 
GeneralRe: Remotely Turn off computer monitor Pin
Giorgi Dalakishvili24-Dec-08 8:11
mentorGiorgi Dalakishvili24-Dec-08 8:11 
AnswerRe: Remotely Turn off computer monitor Pin
Dave Kreskowiak24-Dec-08 9:00
mveDave Kreskowiak24-Dec-08 9:00 
Questionhow to send key from wordpad to c# app Pin
VyTrx24-Dec-08 6:55
VyTrx24-Dec-08 6:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.