PascalScript Eigene Klasse

Rund um die LCL und andere Komponenten
Antworten
compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

PascalScript Eigene Klasse

Beitrag von compmgmt »

Hallo,

ich erstelle gerade mit RemObjects PascalScript eine Addon-Schnittstelle, für eine Software von mir. Wichtig ist mir dabei eine Sicherstellung der Datensicherheit des Benutzers. Deswegen wird jeder Zugriff auf eine Datei abgefangen und der Benutzer muss es erst erlauben, wenn der Zugriff außerhalb eines bestimmten Verzeichnisses ist. Man soll natürlich auch Dinge wie TStringList benutzen können, jedoch kann ich nicht einfach die Komponente für den Import von sysutils und Classes benutzen, da dort ja auch Methoden wie "TStringList.SaveToFile();" existieren. Das würde natürlich ohne Abfrage einfach durchgehen. Deswegen stelle ich die Frage, wie man selbst geschriebene Klassen für das Skript registrieren kann. Ich hab nämlich bisher nicht wirklich was gefunden.

Passendes Beispiel dazu:
FPC-Code:

Code: Alles auswählen

type
  TMyClass = class
    private
      FSomething: Integer;
      procedure SetSomething(i: Integer);
    public
      property FSomething: Integer read FSomething write SetSomething;
end;

PascalScript-Code:

Code: Alles auswählen

var
  MyClass: TMyClass;
begin
  MyClass := TMyClass.Create;
  MyClass.Something := 5;
  MyClass.Free;
end;

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: PascalScript Eigene Klasse

Beitrag von compmgmt »

Also ich habe jetzt mal in die uPSC_classes.pas geschaut, da hab ich zwar gefunden, wie man eine Klasse registriert und es auch mal gleich ausprobiert, aber beim Ausführen des Skriptes gibt es eine Access Violation.
FPC-Code:

Code: Alles auswählen

interface
 
type
  TTestClass = class // Klasse für das Skript
    private
      FTest: String;
      procedure SetTest(s: String);
    public
      constructor Create;
      destructor Destroy;
      property Test: String read FTest write SetTest;
  end;
 
  TAddonHost = class // NICHT für das Skript; Instanz "AddonHost" wird bei initialization erstellt und bei finalization dekonstruiert
    private
      FCurrentAddon: String;
    public
      procedure Event(Method: String; const Params: array of Variant);
      procedure CallAddon(Addon, Method: String; const Params: array of Variant); // Wird aufgerufen, wenn ich das Skript kompilieren und ausführen möchte
      procedure PSOnCompile(Sender: TPSScript);
      property CurrentAddon: String read FCurrentAddon;
  end;
 
...
implementation
...
 
procedure TAddonHost.PSOnCompile(Sender: TPSScript);
begin
  ...
  with Sender do begin
    with Comp.AddClassN(nil, 'TTestClass') do begin
      RegisterMethod('constructor Create;');
      RegisterMethod('destructor Destroy;');
      RegisterMethod('procedure SetTest(s: String);');
      RegisterProperty('Test', 'String', iptRW);
    end;
  end;
end;
 
procedure TAddonHost.CallAddon(Addon, Method: String; const Params: array of Variant); // Wird aufgerufen, wenn ich das Skript kompilieren und ausführen möchte
var
  AddonFile: String;
begin
  AddonFile := CfgPath + 'Addons' + PathDelim + Addon + PathDelim + 'main.pas'; // CfgPath ist in einer anderen Unit definiert.
  if FileExists(AddonFile) then begin
    FCurrentAddon := Addon;
    with TPSScript.Create(Wnd_LazPlan) do begin
      try
        CompilerOptions := [icAllowUnit];
        UsePreProcessor := true;
        OnCompile := @PSOnCompile;
        Script.LoadFromFile(AddonFile);
        if Compile then ExecuteFunction(Params, Method)
           else MessageDlg('LazPlan', 'Error while compiling Addon script file "' + AddonFile + '"' + LineEnding
             + CompilerErrorToStr(0), mtError, [mbOK], 0);
      finally
        Free;
      end;
    end;
  end
  else begin
    FCurrentAddon := '';
    ThrowError(E_FILE_NOT_EXISTS);
  end;
end;


Und dazu der passende PascalScript-Code:

Code: Alles auswählen

program TestAddon;
 
procedure OnTest;
var
  t: TTestClass;
begin
  t := TTestClass.Create;
  t.Test := 'hallo';
  //t.Destroy; // Wenn es nicht auskommentiert ist, kommt die Meldung "Methode DESTROY konnte nicht gefunden werden"
  t := nil;
end;
 
begin
end.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: PascalScript Eigene Klasse

Beitrag von Soner »

Gib basis Klasse an z.b.:

Code: Alles auswählen

 
TTestClass = class(TObject)
 //...
 


Beim Registrieren dasselbe:

Code: Alles auswählen

 
with Sender do begin
    with Comp.AddClassN(cl.FindClass('TObject'), 'TTestClass') do begin
 

Dann musst du auch nicht Destroy registirieren.

Es gibt im original Paket Klassenimporter das kannst du benutzen. In Bin-Ordner PSUnitImporter.exe heißt es.

Bei Lazarus-PascalScript kann TStringList.Create nicht verwendet werden, ich habe bei Lazarus-Bugreport ein Workaround dafür gemeldet, es wurde ignoriert. Wenn du TStringList.Create brauchst, dann schaue in Lazarus-Bugtracker.

Edit:
Ich würde in deiner Stelle für die Sicherheitseinstellungen direkt Pascalscript ändern, das ist dann weniger Arbeit. Ich mache das immer, LCL, FCL und vieles ändere ich und notiere für die zukunftige Lazarusversionen die Änderungen. Das ist viel einfacher als komplett neu schreiben.

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: PascalScript Eigene Klasse

Beitrag von compmgmt »

Soner hat geschrieben:Gib basis Klasse an z.b.:

Code: Alles auswählen

 
TTestClass = class(TObject)
 //...
 


Beim Registrieren dasselbe:

Code: Alles auswählen

 
with Sender do begin
    with Comp.AddClassN(cl.FindClass('TObject'), 'TTestClass') do begin
 

Dann musst du auch nicht Destroy registirieren.
Hab ich auch schon mit TObject als Vererber probiert, hat nicht geklappt.

Soner hat geschrieben:Es gibt im original Paket Klassenimporter das kannst du benutzen. In Bin-Ordner PSUnitImporter.exe heißt es.
Ah, ok. Vielen Dank.

Soner hat geschrieben:Bei Lazarus-PascalScript kann TStringList.Create nicht verwendet werden, ich habe bei Lazarus-Bugreport ein Workaround dafür gemeldet, es wurde ignoriert. Wenn du TStringList.Create brauchst, dann schaue in Lazarus-Bugtracker.

Edit:
Ich würde in deiner Stelle für die Sicherheitseinstellungen direkt Pascalscript ändern, das ist dann weniger Arbeit. Ich mache das immer, LCL, FCL und vieles ändere ich und notiere für die zukunftige Lazarusversionen die Änderungen. Das ist viel einfacher als komplett neu schreiben.
Ok, vielen Dank.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: PascalScript Eigene Klasse

Beitrag von Soner »

Hast du die Klasse auch bei TPSScript.OnExecute importiert?
Klassen und Funktionen müssen beim Kompilieren(OnCompile) und beim Ausführen(OnExecute) registiert werden.

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: PascalScript Eigene Klasse

Beitrag von compmgmt »

Soner hat geschrieben:Hast du die Klasse auch bei TPSScript.OnExecute importiert?
Klassen und Funktionen müssen beim Kompilieren(OnCompile) und beim Ausführen(OnExecute) registiert werden.
Nein, ich hab alles nur beim OnCompile registriert. Das könnte der Grund sein, weshalb es zu einer Zugriffsverletzung kommt.

Nochmal zum Import-Tool: Wo genau befindet sich das Tool? Ich hab unter https://github.com/remobjects/pascalscript zwar eine Icon-Datei mit dem Namen gefunden, aber keine fertige exe oder Projektdatei zum selbst kompilieren.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: PascalScript Eigene Klasse

Beitrag von Soner »

PSUnitImporter habe ich hier hochgeladen:
https://1drv.ms/u/s!AvJGv-C_3b-WgQtLL8I3ApBS6Qkl
Es ist compiliertes Programm, Quelltext lag nicht dabei.

Hier wird erklärt Klassen verwendet werden:
https://github.com/remobjects/pascalscript/wiki/Using-Classes-with-RemObjects-PascalScript

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: PascalScript Eigene Klasse

Beitrag von Mathias »

Ich habe dein ersten Post angeguckt.

Code: Alles auswählen

property FSomething:

Sollte dort nicht Something anstelle FSomething stehen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: PascalScript Eigene Klasse

Beitrag von compmgmt »

Mathias hat geschrieben:Ich habe dein ersten Post angeguckt.

Code: Alles auswählen

property FSomething:

Sollte dort nicht Something anstelle FSomething stehen ?

Ja, sollte es. Aber das war nur ein Beispiel schnell so getippt. Das habe ich nie real verwendet. Nur die TTestClass ist per Copy&Paste tatsächlich aus meinem Programmcode.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: PascalScript Eigene Klasse

Beitrag von compmgmt »

Soner hat geschrieben:PSUnitImporter habe ich hier hochgeladen:
https://1drv.ms/u/s!AvJGv-C_3b-WgQtLL8I3ApBS6Qkl
Es ist compiliertes Programm, Quelltext lag nicht dabei.
Vielen Dank für deine Bemühungen :D

Soner hat geschrieben:Hier wird erklärt Klassen verwendet werden:
https://github.com/remobjects/pascalscript/wiki/Using-Classes-with-RemObjects-PascalScript
Ja, die Seite hatte ich auch schon aufgerufen, aber da hab ich den Download nicht gefunden.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Antworten