2012-12-08 27 views
1

嗨,我寫了下面的代碼:C#system.reflection.emit ldfld

 AssemblyName assemblyName = new AssemblyName("SamAsm"); 
     AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); 
     TypeBuilder typeBuilder = assemblyBuilder.DefineDynamicModule("SamAsm.exe").DefineType("SamAsmType", TypeAttributes.Public); 
     MethodBuilder methodBuilder1 = typeBuilder.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), new Type[] { typeof(string) }); 
     ILGenerator gen = methodBuilder1.GetILGenerator(); 
     FieldInfo field1 = typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

     MethodInfo method2 = typeof(Control).GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod(); 
     MethodInfo method3 = typeof(String).GetMethod(
      "op_Equality", 
      BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, 
      null, 
      new Type[]{ 
    typeof(String), 
    typeof(String) 
    }, 
      null 
      ); 
     MethodInfo method4 = typeof(MessageBox).GetMethod(
      "Show", 
      BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, 
      null, 
      new Type[]{ 
    typeof(String) 
    }, 
      null 
      ); 



     LocalBuilder a = gen.DeclareLocal(typeof(Boolean)); 

     System.Reflection.Emit.Label label42 = gen.DefineLabel(); 

     gen.Emit(OpCodes.Nop); 
     gen.Emit(OpCodes.Ldarg_0); 
     gen.Emit(OpCodes.Ldfld, field1); 
     gen.Emit(OpCodes.Callvirt, method2); 
     gen.Emit(OpCodes.Ldstr, "HI"); 
     gen.Emit(OpCodes.Call, method3); 
     gen.Emit(OpCodes.Ldc_I4_0); 
     gen.Emit(OpCodes.Ceq); 
     gen.Emit(OpCodes.Stloc_0); 
     gen.Emit(OpCodes.Ldloc_0); 
     gen.Emit(OpCodes.Brtrue_S, label42); 
     gen.Emit(OpCodes.Nop); 
     gen.Emit(OpCodes.Ldstr, "You cracked me"); 
     gen.Emit(OpCodes.Call, method4); 
     gen.Emit(OpCodes.Pop); 
     gen.Emit(OpCodes.Nop); 
     gen.MarkLabel(label42); 
     gen.Emit(OpCodes.Ret); 




     typeBuilder.CreateType().GetMethod("Main").Invoke(null, new string[] { null }); 
     assemblyBuilder.SetEntryPoint(methodBuilder1, PEFileKinds.WindowApplication);} 

當我嘗試這一點,停止我的 gen.Emit(OpCodes.Ldfld的typeof(Form 1中).GetField(」 TextBox1「,BindingFlags.Public | BindingFlags.NonPublic));

並告訴:該值不能爲空。參數名稱:con。 有人可以幫助我嗎?

+2

對你要做什麼的一些解釋會很有幫助,所以你不需要解釋你的代碼就可以得到線索...... – poplitea

+1

嗯,你傳遞的值是'null'嗎?另外,你可以發佈堆棧跟蹤,因爲'Emit()'的重載沒有一個名爲'con'的參數。 – svick

+0

我想把文本插入文本框中,然後檢查它是否等於「HI」 問題是,當我運行嘗試時,它阻止了我在ldfld上。這是一張圖片:http://gyazo.com/6573b8e2f6578274f183aff84af9831b.png?1355049891 – user1872492

回答

2

這意味着對於調用的參數之一爲空,最有可能的的typeof(Form 1中).GetField(「TextBox1的」,BindingFlags.Public | BindingFlags.NonPublic)的返回值

由於您已將該值存儲在變量field1中,您應該進入調試模式並檢查它是否爲空。

如果該值爲空,則可能意味着不同的事情:

  • 是否真的有所謂的TextBox1的領域在Form1類?總是懷疑 - 檢查拼寫,還有字符大小寫。像GetField,GetProperty等反射方法是區分大小寫的,除非與BindingFlags.IgnoreCase一起使用。
  • 它是否可以使用您提供的BindingFlags的值(例如它是靜態的?)?

在你的情況,如果你看一下MSDN documentation的getfield命令,它明確地指出:

以下的BindingFlags過濾標誌可用於定義字段在搜索中包括:

您必須指定BindingFlags.Instance或BindingFlags.Static才能獲得返回

指定BindingFlags.Public在搜索中包含公共字段。

指定BindingFlags.NonPublic在搜索中包含非公用字段(即私有字段,內部字段和受保護字段)。

指定BindingFlags.FlattenHierarchy在層次結構中包含公共和受保護的靜態成員;不包括繼承類中的私有靜態成員。

所以你應該使用BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance而不是BindingFlags.Public |的BindingFlags。非公開

而且取代

gen.Emit(OpCodes.Ldfld,typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)); 

隨着

gen.Emit(OpCodes.Ldfld, field1); 

並使用你在哪裏要分配FIELD1行了適當的標誌。

UPDATE:您對Main的最終調用有同樣的問題。您需要在下面的代碼行指定BindingFlags.Static,sinhce您使用MethodAttributes早些時候在你的代碼中定義的方法爲靜態:

typeBuilder.CreateType().GetMethod("Main", BindingFlags.Static | BindingFlags.Public).Invoke(null, new string[] { null }); 

Additionnally,你不想來檢索屬性訪問你正在做的方式它:而不是使用GetMethod與存取(get_Text)的名字,你應該使用的getProperty:

MethodInfo method2 = typeof(Control).GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetMethod; 

希望有所幫助。

+0

非常感謝您的回答。然而:我addes bindingflags.instance也,但當我去調試時,當它阻止我在ldfld線,我可以看到field1的值爲空..我如何解決?在form1類中有一個名爲TextBox1的字段,它可以被訪問。 – user1872492

+0

我現在更新了代碼。 – user1872492

+0

我猜這是因爲你的文本框的名字實際上是textBox1而不是TextBox1(GetField是區分大小寫的,除非你使用BindingFlags.IgnoreCase)......但它只是一個瘋狂的猜測...... –

2

這似乎很可能在這裏,下面是返回null

typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic) 

我眼前的猜測是,你需要一個BindingFlags.Instance添加到組標誌,它返回現場。