Einzelnen Beitrag anzeigen

Vasco da Gama

Registriert seit: 2. Aug 2009
131 Beiträge
 
Delphi 2009 Professional
 
#9

Re: ScriptEngine II (v. 0.3.2.4)

  Alt 22. Sep 2009, 17:00
Hi, ich wollte deine Engine mal wie in der .pdf Datei beschrieben ausprobieren.
vor punkt 2.4 scheitere ich, ich zitiere:
Zitat:
Wenn das Programm jetzt ausgeführt wird, werden zwar keine Fehlermeldungen mehr angezeigt, jedoch wird auch keine Zahl angezeigt. Das liegt jetzt aber nicht daran, dass das Script nicht ausgeführt wird – im Gegenteil. Es liegt nur daran, dass die Output-Methode der Script-Engine-Console noch nicht gesetzt ist. Doch das kann man schnell ändern.
Allerdings bekomme ich bei folgendem Code:
Delphi-Quellcode:
unit testunit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,
  uSE2Compiler, // für den Compiler
  uSE2UnitCacheMngr, // für den Unit-Cache-Manager
  uSE2Errors, // für TSE2ErrorType
  uSE2Reader, // wird zum Lesen der Daten benutzt
  uSE2PEData, // die ByteCode-Daten
  uSE2RunTime; // für die RunTime

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure CompilerError(Sender: TObject; ErrorType: TSE2ErrorType; ErrorUnit, ErrorText: string; ErrorPos, ErrorLine: integer; UserData: TObject);
    procedure CompilerNeedUnit(Sender: TObject; const Name: string; const Readers: TList);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  Compiler : TSE2Compiler;
  RunTime : TSE2RunTime;
  PEData : TSE2PE;
begin
  Compiler := TSE2Compiler.Create;// den Compiler erstellen
  try // hier wird der Quelltext des Scripts compiliert
    Compiler.OnGetFile := CompilerNeedUnit;
    Compiler.OnCompilerError := CompilerError;
    PEData := Compiler.Compile(
              'program MyScript;'
              +#13#10+ 'uses MyUnit;'
              +#13#10+ 'var i: integer;'
              +#13#10+ 'begin'+#13#10+ ' i := Add(2, 4);'
              +#13#10+ ' Console.WriteLine(i);'
              +#13#10+ 'end.'+#13#10); // falls das compilieren erfolgreich war, ist PEData ungleich nil
    if PEData <> nil then
    begin
      try // hier wird die RunTime erstellt, die das kompilierte
          // Script ausführt
        RunTime := TSE2RunTime.Create;
        try
          // zuerst muss das kompilierte Script übergeben werden
          RunTime.AppCode := PEData; // nun muss die RunTime initialisiert werden
          RunTime.Initialize; // hier wird das Script ausgeführt
          RunTime.Run; // nun noch die RunTime stoppen
          RunTime.Finalize; // wenn wir folgende Zeile nicht einfügen
          // RunTime.AppCode := nil
          // wird das Objekt PEData automatisch von der RunTime
          // freigegeben.
          // Da wir das aber selbst machen, fügen wir die Zeile ein RunTime.AppCode := nil;
        finally
          // die RunTime freigeben
          RunTime.Free;
        end;
      finally
        // das kompilierte Skript freigeben
        PEData.Free;
      end;
    end;
  finally // den Compiler freigeben
    Compiler.Free;
  end;
end;

procedure TForm1.CompilerError(Sender: TObject; ErrorType: TSE2ErrorType; ErrorUnit, ErrorText: string; ErrorPos, ErrorLine: integer; UserData: TObject);
begin
  // nur Fehler anzeigen
  if ErrorType = petError then // Fehlernachricht anzeigen
    ShowMessage('Compiler error: '+#13#10+ Format('[%s] [Zeile %d]: %s', [ErrorUnit, ErrorLine, ErrorText] ) );
end;

procedure TForm1.CompilerNeedUnit(Sender: TObject; const Name: string; const Readers: TList);
begin
  // falls der Compiler die Unit "MyUnit" haben will
  if SameText(Name, 'MyUnit') then
  begin
    // dann wird er Quelltext der Unit hinzugefügt
    // dazu muss in der Liste "Readers" ein Objekt vom
    // Typ "TSE2Reader" hinzufügen. Jedoch ist "TSE2Reader"
    // eine abstrakte Klasse. Vom Reader sind zwei Versionen
    // bei der Script-Engine mit dabei:
    // - ein StringReader, mit dem man direkt den Quelltext als
    // string übergeben kann
    // - ein StreamReader, mit dem man den Stream mit dem Quelltext
    // auslesen kann
     // da hier direkt ein String benutzt wird, wird der TStringReader
     // benutzt
     Readers.Add( TSE2StringReader.Create(
        // nun übergibt man im Constructor direkt den Quelltext
        // der Unit "MyUnit"
        'unit MyUnit;'+#13#10+
        'interface'+#13#10+
        ' function Add(const i1, i2: integer): integer;'+#13#10+
        'implementation'+#13#10+
        ' function Add(const i1, i2: integer): integer;'+#13#10+
        ' begin result := i1 + i2;end;'+#13#10+
        'end.' ) );
     end;
end;

end.
Bei Programmstart eine Fehlermeldung:
Erste Gelegenheit für Exception bei $7572FBAE. Exception-Klasse EInvalidPointer mit Meldung 'Ungültige Zeigeroperation'. Prozess TestProject.exe (1676)

So sagt mir das zumidest der Debugger

Ich hoffe du kannst mir helfen.

mfG
Flo
Programmiere inzwischen hauptsächlich mit C++. Nicht böse werden
  Mit Zitat antworten Zitat