2012-12-03 11 views
4

我試圖做ilgenerator.emit一個MsgBox但我有一個例外,當我運行代碼:使用System.Reflection.Emit顯示在Windows.Forms的一個MessageBox

exception generated from destination of a call

這是我的代碼:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    Dim assemblyName As AssemblyName = New AssemblyName("SamAsm") 
    Dim assemblyBuilder As AssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave) 

    'Creating module 
    Dim moduleBuilder As ModuleBuilder = assemblyBuilder.DefineDynamicModule("SamAsm.exe") 

    Creating class file 
    Dim typeBuilder As TypeBuilder = moduleBuilder.DefineType("SamAsmType", TypeAttributes.Public Or TypeAttributes.Class) 

    Creating Main Method 
    Dim methodBuilder1 As MethodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Static Or MethodAttributes.Public, GetType(Void), New System.Type() {GetType(String)}) 

    'Generating Code for method builder in IL 
    Dim ilGenerator As ILGenerator = methodBuilder1.GetILGenerator 
    ilGenerator.Emit(OpCodes.Ldstr, "test") 
    ilGenerator.EmitCall(OpCodes.Call, GetType(System.Windows.Forms.MessageBox).GetMethod("Show", {GetType(String)}), {GetType(String)}) 
    ilGenerator.Emit(OpCodes.Ret) 

    'Creating Class object (type) and accessing main method 
    Dim SamAsmType As Type = typeBuilder.CreateType 
    SamAsmType.GetMethod("Main").Invoke(Nothing, New String() {Nothing}) 

    'Creating Entry Point and saving assembly 
    assemblyBuilder.SetEntryPoint(methodBuilder1, PEFileKinds.WindowApplication) 
    assemblyBuilder.Save("SamAsm.exe") 
End Sub 
+0

第一寫C#或VB.NET代碼,使用程序Ildasm.exe來看看IL。 –

回答

4

你必須確保從Sub/void函數返回時堆棧爲空。

Show -Method返回DialogResult,因此您必須致電Pop以從堆棧中刪除DialogResult

... 
ilGenerator.EmitCall(OpCodes.Call, GetType(System.Windows.Forms.MessageBox).GetMethod("Show", {GetType(String)}), {GetType(String)}) 
ilGenerator.Emit(OpCodes.Pop) ' remove the return value of Show from the stack 
ilGenerator.Emit(OpCodes.Ret) 
... 

然而,你可以隨時使用peverify追查錯誤在你的動態創建的組件。

你的情況

所以,在SamAsm.exe peverify運行會給你以下錯誤:

[IL]: Error: [c:\yourpath\SamAsm.exe : SamAsmType::Main][offset 0x0000000A] Stack must be empty on return from a void function. 1 Error(s) Verifying SamAsm.exe

+0

非常感謝Dominic!我可以問另一件事嗎? (我與排放新)..我怎麼能做一個,如果與brfalse檢查?因爲像brfalse或brtrue這樣的指令指向另一條指令,我不知道該怎麼做!謝謝 – user1872492