open System
open Mono.Cecil
open Mono.Cecil.Cil
let myHelloWorldApp =
AssemblyDefinition.CreateAssembly(
new AssemblyNameDefinition("HelloWorld", new Version(1, 0, 0, 0)), "HelloWorld", ModuleKind.Console)
let module_ = myHelloWorldApp.MainModule
// create the program type and add it to the module
let programType =
new TypeDefinition("HelloWorld", "Program",
Mono.Cecil.TypeAttributes.Class ||| Mono.Cecil.TypeAttributes.Public, module_.TypeSystem.Object)
module_.Types.Add(programType)
// add an empty constructor
let ctor =
new MethodDefinition(".ctor", Mono.Cecil.MethodAttributes.Public ||| Mono.Cecil.MethodAttributes.HideBySig
||| Mono.Cecil.MethodAttributes.SpecialName ||| Mono.Cecil.MethodAttributes.RTSpecialName, module_.TypeSystem.Void)
// create the constructor's method body
let il = ctor.Body.GetILProcessor()
il.Append(il.Create(OpCodes.Ldarg_0))
// call the base constructor
il.Append(il.Create(OpCodes.Call, module_.ImportReference(typeof<obj>.GetConstructor([||]))))
il.Append(il.Create(OpCodes.Nop))
il.Append(il.Create(OpCodes.Ret))
programType.Methods.Add(ctor)
// define the 'Main' method and add it to 'Program'
let mainMethod =
new MethodDefinition("Main",
Mono.Cecil.MethodAttributes.Public ||| Mono.Cecil.MethodAttributes.Static, module_.TypeSystem.Void)
programType.Methods.Add(mainMethod)
// add the 'args' parameter
let argsParameter =
new ParameterDefinition("args",
Mono.Cecil.ParameterAttributes.None, module_.ImportReference(typeof<string[]>))
mainMethod.Parameters.Add(argsParameter);
// create the method body
il = mainMethod.Body.GetILProcessor()
il.Append(il.Create(OpCodes.Nop))
il.Append(il.Create(OpCodes.Ldstr, "Hello World"))
let writeLineMethod =
il.Create(OpCodes.Call,
module_.ImportReference(typeof<Console>.GetMethod("WriteLine", [|typeof<string>|])))
// call the method
il.Append(writeLineMethod)
il.Append(il.Create(OpCodes.Nop))
il.Append(il.Create(OpCodes.Ret))
// set the entry point and save the module
myHelloWorldApp.EntryPoint <- mainMethod
Ich habe the example aus der Antwort auf diese Frage ausgeliehen und neu in F # geschrieben. Wenn ich versuche, es auszuführen, erhalte ich den folgenden Fehler:Warum schlägt das Mono.Cecil HelloWorld-Beispiel mit einer Ausnahme fehl?
Unhandled Exception: System.TypeLoadException: Could not load type 'HelloWorld.Program' from assembly 'Hello
on=1.0.0.0, Culture=neutral, PublicKeyToken=null' because the method 'Main' has no implementation (no RVA).
Was ist hier falsch?
Ja, das war es. Anstatt eine let-Anweisung zu verwenden, wäre es besser, sie an ein Lambda zu binden, da andernfalls der doppelte Variablenfehler auftritt. Außerdem habe ich schon einmal bemerkt, dass F # mir aus irgendeinem Grund nicht die übliche Einheitswarnung auf dem Gleichheitstest gibt, aber es kam mir nicht in den Sinn, nochmal nach dem gleichen Fehler zu suchen. Vielen Dank. –
@MarkoGrdinic Sie erhalten die Gleichheitstestwarnung nicht auf oberster Ebene in einem Skript (wo Sie vielleicht eine Anzahl von Ausdrücken schreiben und sie nacheinander ausführen möchten). Sie würden diese bekommen, wenn Ihr Code innerhalb einer Funktion wäre (was sowieso eine bessere Struktur ist) –