Einzelnen Beitrag anzeigen

Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#14

AW: Skript-Engine integrieren

  Alt 24. Aug 2010, 15:49
Ok, ich versuche mal eine Schnell-Anleitung zu geben, wie man das ganze am schnellsten macht (nicht abschrecken von den paar Punkten - habe versucht es möglich genau zu machen.
  • Öffne die Beispiel-IDE, die mit im Download-Paket im Ordner "IDE" enthalten ist
  • Erstelle ein neues Projekt (ist egal wie es heißt)
  • Klicke mit der rechten Maustaste im Tab "Project" auf den oberen Eintrag in der TreeView und wähle den Eintrag "Add new Unit"
  • Gib den Unit-Names "SkriptCommands" ein und drücke ok
  • Wiederhole das ganze mit "Murmel" und "Skripting"
  • Nun kannst du die Units per Doppelklick auf den entsprechenden Eintrag öffnen
  • Fülle den Inhalt der Units entsprechend aus (also das, was bei dir in der Konstante C_UnitSource steht
  • Wiederhole das mit "Murmel" und "Skripting"
  • Gehe nun in den ersten Tab bei der Quelltext-Liste (da wo die Units offen sind) (program ... etc.)
  • Füge deine hinzugefügten Units in die Uses-Liste hinzu (es sollte keine uses-Liste vorhanden sein, also einfach ganz normal erstellen)
  • Nun solltest du kompilieren können.
  • Jetzt wählst du wieder den Tab der Unit "SkriptCommands" aus.
  • Dann klickst du im Hauptmenü unter "Project" auf "Generate Unit" -> "Application Unit"
  • Es wird ein neuer Tab erstellt, in dem der komplett fertige Delphi-Quelltext drinnen steht. Diesen kopierst du einfach in die Zwischenablage und fügst ihn in eine neue Unit in deinem Projekt hinzu. Wahrscheinlich musst du noch ein paar uses-Sachen für die entsprechenden Typen anpassen, aber und vielleicht ein paar Methoden - aber es sollte eigentlich funktionieren
  • Wiederhole die letzten 3 Punkte mit den Units "Murmel" und "SkriptCommands"

Die neuen Units, die du gerade erstellt hast, solltest du nicht mehr groß erweitert. Die sind nur dafür da, um die Script-Engine mit deinen Methoden usw. zu füllen.

Jetzt baue ich dein Beispiel-Script nach, wie es eigentlich funktionieren sollte (hab gerade kein Delphi zur Hand, daher ist alles nur ausm Kopf heraus geschrieben)

Erstelle in deinem Delphi-Projekt eine neue Unit und schreibe folgenden Quelltext hinein:
Delphi-Quellcode:
unit [was auch immer]

interface

procedure RunScript(const ScriptSource: string);

implementation

uses
  uSE2Compiler, uSE2RunTime, uSE2PEData;

procedure RunScript(const ScriptSource: string);
var Compiler: TSE2Compiler;
    PEData : TSE2PE;
    RunTime : TSE2RunTime;
begin
  Compiler := TSE2Compiler.Create;
  try
    // Compilieren
    PEData := Compiler.Compile(ASkript);
    if PEData <> nil then
    begin
      // Compilieren erfolgreich - PEData muss nicht manuell
      // freigegeben werden, da die RunTime das für uns erledigt.
      // Daher gibt es hier für PEData keinen try-finally-Block
      RunTime := TSE2RunTime.Create;
      try
        RunTime.AppCode := PEData;

        // RunTime initialisieren
        RunTime.Initialize;
        // ausführen
        RunTime.Run;
        // aufräumen
        RunTime.Finalize;
      finally
        // wie gesagt, PEData wird hier mit freigegeben
        RunTime.Free;
      end;
    end;
  finally
    Compiler.Free;
  end;
end;

end.
Folgende Punkte sind im PDF für dich noch wichtig:
  • 2.2 Auf Compiler-Fehler reagieren
  • 2.5 Auf Laufzeitfehler reagieren - denn dein (except-block mit ShowMessage('Beim Ausführen des Skripts ist ein Fehler aufgetreten!'); wird nur bei wirklich fatalen Fehlern erreicht - alle Exceptions innerhalb eines Scriptes (z.B. Dividieren durch 0) müssen anders behandelt werden

Was ich auch noch erwähnen wollte: die SEII ist nicht dazu optimiert, ständig den Quelltext zu kompilieren und diesen dann direkt auszuführen. Die SEII ist für das Ausführen von Scripten extrem optimiert (schneller als Pascal-Script, Sysygy, Delphi++, etc...). Daher wäre es sinnvoll, dein Script einmal durch den Compiler zu jagen und dir das TSE2PE-Objekt zu merken. Aber das nur so am Rande, jetzt schau ma erstmal, dass dein Basis-Ding funktioniert
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat