Ich schreibe gerade ein Programm welches unter dem Raspberry Pi laufen soll jedoch scheitere ich daran unter PascalScript mittels AddFunktion eine Funktion zu übergeben.
Gleiches Problem besteht auch darin mittels AddMethod eine Prozedur oder Funktion zu übergeben. Diesen Umstand habe ich bis gestern auch so akzeptiert und mir mittels einer zusätzlichen Globalen Klasse dann die Variablen auch geholt. Das Klappte wunderbar unter Windows/Delphi und Windows/Lazarus(Intel). Ohne Probleme wurde der Source auch von Lazarus unter dem RPI kompiliert jedoch beim ausführen des Testscripts brach er dann auch hier immer wieder ab wenn eine Funktion aufgerufen wurde. Habe mittels Debugger dann gemerkt das er "Müll" an die Funktion übergibt und desshalb aussteigt. Selbst dan der hinzugefügten Funktion Now und Format scheitert es.
Es gibt eine Basisklasse TScriptEngine, diese erzeugt für jedes Script vor dem Starten eine "Instanz" in der alle Daten für das Script drin sind. Dies nutze ich um die Variablen aus den RS232 Modulen zu bekommen und um dort SQL Queries abzulegen.
Wie gesagt es ist sehr einfach gehalten vom Ablauf her.
Das hier ist die original Funktion:
Code: Alles auswählen
function PS_GetDevice(const S: string): string;
var
ScriptEngineObjs: TScriptEngineObjs;
Index: Integer;
begin
WriteLn('PROC::GetDevice::ENTER');
WriteLn('PROC::GetDevice::Instanz=' + S); // Absturz bzw. der Thread beendet sich. In S stehen nicht sichtbare Zeichen. Sollte aber sein 12356456456_Script3.pas
if ScriptEngine.FindInstance(S, Index) then
begin
WriteLn('PROC::GetDevice::Instance found');
ScriptEngineObjs := ScriptEngine.GetInstance(Index);
Result := ScriptEngineObjs.Device;
end
else
WriteLn('PROC::GetDevice::Instance not found');
WriteLn('PROC::GetDevice::END');
end;
Baue ich die Funktion in eine Prozedur um dann läuft sie anstandslos
Code: Alles auswählen
procedure PS_GetDevice2(Instance: string; var ADevice: string);
var
ScriptEngineObjs: TScriptEngineObjs;
Index: Integer;
begin
WriteLn('PROC::GetDevice::ENTER');
WriteLn('PROC::GetDevice::Instanz=' + Instance);
if ScriptEngine.FindInstance(Instance, Index) then
begin
WriteLn('PROC::GetDevice::Instance found');
ScriptEngineObjs := ScriptEngine.GetInstance(Index);
ADevice := ScriptEngineObjs.Device;
end
else
WriteLn('PROC::GetDevice::Instance not found');
WriteLn('PROC::GetDevice::END');
end;
Meine OnCompile sah so aus
Code: Alles auswählen
procedure TScriptEngineThread.PSCompile(Sender: TPSScript);
begin
Sender.AddFunction(@PS_WriteLn, 'procedure WriteLn(const S: string);');
Sender.AddFunction(@PS_GetDevice, 'function GetDevice(const S: string): string;'); // Fehler
//Sender.AddFunction(@PS_GetDevice2, 'procedure GetDevice(Instance: string; var ADevice: string);'); // läuft
Sender.AddFunction(@PS_GetModul, 'function GetModul(Instance: string): string;');
Sender.AddFunction(@PS_GetParam, 'function GetParam(Instance: string): string;');
Sender.AddFunction(@PS_GetData, 'function GetData(Instance: string): string;');
Sender.AddFunction(@PS_WriteToModul, 'procedure WriteToModul(Device: string; Modul: string; Param: string; Data: string);');
// SQL Communication
Sender.AddFunction(@PS_QueryAdd, 'function QueryAdd(Instance, Name: string): Boolean);');
Sender.AddFunction(@PS_QueryRem, 'function QueryRem(Instance, Name: string): Boolean);');
Sender.AddFunction(@PS_Query, 'procedure Query(Instance, Name: string; SQL: string);');
Sender.AddFunction(@PS_QueryRecordCount, 'function QueryRecordCount(Instance, Name: string): Integer;');
Sender.AddFunction(@PS_QueryRowsAffected, 'function QueryRowsAffected(Instance, Name: string): Integer;');
Sender.AddFunction(@PS_QueryFirst, 'procedure QueryFirst(Instance, Name: string);');
Sender.AddFunction(@PS_QueryLast, 'procedure QueryLast(Instance, Name: string);');
Sender.AddFunction(@PS_QueryNext, 'procedure QueryNext(Instance, Name: string);');
Sender.AddFunction(@PS_QueryPrior, 'procedure QueryPrior(Instance, Name: string);');
Sender.AddFunction(@PS_QueryEof, 'function QueryEof(Instance, Name: string): Boolean;');
Sender.AddFunction(@PS_QueryReadAsInt, 'function QueryReadAsInt(Instance, Name: string; Fieldname: string): Integer;');
Sender.AddFunction(@PS_QueryReadAsStr, 'function QueryReadAsStr(Instance, Name: string; Fieldname: string): string;');
Sender.AddFunction(@PS_QueryReadAsFloat, 'function QueryReadAsFloat(Instance, Name: string; Fieldname: string): Double;');
Sender.AddFunction(@PS_QueryReadAsBoolean, 'function QueryReadAsFloat(Instance, Name: string; Fieldname: string): Boolean;');
// Sender.AddFunction(@PS_GetDBData, 'function DBData(Device: string; Modul: string; Param: string): string;');
Sender.AddFunction(@Format, 'function Format(const Format: string; const Args: array of const): string;');
Sender.AddFunction(@Sleep, 'procedure Sleep(milliseconds: Cardinal);');
Sender.AddFunction(@PS_DateTimeToStr, 'function DateTimeToStr(const DateTime: Double): string;');
Sender.AddFunction(@PS_Now, 'function Now: Double;');
end;
Standard Funktionen wie StrToInt/IntToStr laufen dagegen. diese sind ja schon im PascalScript enthalten. Es sollte also auch möglich sein diese so zu übergeben, denke ich zumindest.
Ich nutze:
Raspbian
Lazarus/FP v1.2.4+dfsg2-1
PascalScript auch die aktuellste von Git
Kennt jemand bereits dieses Problem und konnte es lösen?
Bin für jede Hilfe dankbar.
MfG
Daniel