Blockly review

This commit is contained in:
Michael Schimmel
2025-06-11 01:33:52 +02:00
parent b8a530254d
commit 3cfca1f167
4 changed files with 248 additions and 242 deletions
+48 -24
View File
@@ -9,24 +9,34 @@ type
// Callback-Prozedur, die von der DLL aufgerufen wird
TLogIntegerCallback = procedure( AValue: Integer ); stdcall;
// Signatur der exportierten DLL-Funktion
TStarteLogikProc = procedure( ALogCallback: TLogIntegerCallback ); stdcall;
// NEU: Typ für die Host-Additionsfunktion
THostAddIntegersCallback = function( ANum1: Integer; ANum2: Integer ): Integer; stdcall;
// NEUE, VEREINFACHTE Signatur der exportierten DLL-Funktion
// Jetzt nur noch der Log-Callback und der neue Integer-Input-Parameter
TStarteLogikProc = procedure(
ALogIntProc: TLogIntegerCallback;
AHostInputInteger: Integer;
AHostAddIntegersProc: THostAddIntegersCallback // <--- Der neue Host-Unterprogramm-Parameter
); stdcall;
type
TLLVMRunner = class
private
FModule: HMODULE;
FStarteLogik: TStarteLogikProc;
class var
FLog: TStrings;
class procedure LogInteger( AValue: Integer ); static; stdcall;
public
constructor Create(const ADLLPath: string);
destructor Destroy; override;
procedure Execute;
class property Log: TStrings read FLog write FLog;
end;
TLLVMRunner = class
private
FModule: HMODULE;
FStarteLogik: TStarteLogikProc;
class var
FLog: TStrings;
class procedure LogInteger( AValue: Integer ); static; stdcall;
// NEU: Host-Unterprogramm-Implementierung
class function HostAddIntegers( ANum1: Integer; ANum2: Integer ): Integer; static; stdcall;
public
constructor Create(const ADLLPath: string);
destructor Destroy; override;
procedure Execute( AInputInteger: Integer );
class property Log: TStrings read FLog write FLog;
end;
implementation
{ TLLVMRunner }
@@ -50,19 +60,33 @@ begin
inherited;
end;
procedure TLLVMRunner.Execute;
begin
if Assigned( FStarteLogik ) then
// Führe die DLL-Funktion aus und übergebe unsere Callback-Methode
FStarteLogik( LogInteger );
// NEUE Implementierung der Host-Funktion
class function TLLVMRunner.HostAddIntegers( ANum1: Integer; ANum2: Integer ): Integer;
begin
Result := ANum1 + ANum2; // Die eigentliche Logik
if Assigned(FLog) then
FLog.Add(Format('DLL hat Host-Addition angefordert: %d + %d = %d', [ANum1, ANum2, Result]));
end;
// Die Execute-Methode muss angepasst werden, um den neuen Funktionszeiger zu übergeben
procedure TLLVMRunner.Execute( AInputInteger: Integer );
begin
if Assigned( FStarteLogik ) then
FStarteLogik(
LogInteger,
AInputInteger,
HostAddIntegers // <--- Adresse der Host-Funktion übergeben
);
end;
// Dies ist die Methode, die die DLL aufruft.
// Sie muss "static" (class procedure) sein, um eine feste Adresse zu haben.
// Dies ist die Methode, die die DLL für LogInteger aufruft.
class procedure TLLVMRunner.LogInteger( AValue: Integer );
begin
if Assigned( FLOg ) then
if Assigned( FLog ) then
FLog.Add( Format( 'DLL logged integer: %d', [AValue] ) );
end;
// Die Implementierungen von GetCurrentDateTimeUTCHost und GetComponentInZoneHost
// wurden hier entfernt, da sie nicht mehr benötigt werden.
end.
+14 -1
View File
@@ -30,7 +30,7 @@ object MainForm: TMainForm
Size.PlatformDefault = False
Text = 'Refresh'
TextSettings.Trimming = None
OnClick = LauchSiteButtonClick
OnClick = RefreshButtonClick
end
object SaveWorkspaceButton: TSpeedButton
Align = Left
@@ -52,6 +52,19 @@ object MainForm: TMainForm
TextSettings.Trimming = None
OnClick = GenerateCodeButtonClick
end
object InputEdit: TEdit
Touch.InteractiveGestures = [LongTap, DoubleTap]
Align = Left
TabOrder = 3
Text = '1345'
Position.X = 240.000000000000000000
Position.Y = 10.000000000000000000
Margins.Top = 10.000000000000000000
Margins.Bottom = 10.000000000000000000
Size.Width = 73.000000000000000000
Size.Height = 20.000000000000000000
Size.PlatformDefault = False
end
end
end
object Memo: TMemo
+76 -58
View File
@@ -5,30 +5,29 @@ interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls, FMX.WebBrowser,
Winapi.WebView2, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo,
Winapi.WebView2, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.Edit, FMX.StdActns,
// FMX.Edit für TEdit, FMX.StdActns oft für Standardaktionen
// Korrekte und vollständige Units
System.IOUtils, System.Threading, System.Diagnostics, Winapi.Windows, LLVM.Runner;
const
// Pfad zur HTML-Datei
PATH_BLOCKLY = 'T:\Myc\Blockly\index.html';
// Pfad zur HTML-Datei (BITTE HIER ANPASSEN!)
PATH_BLOCKLY = 'T:\Myc\Blockly\index.html'; // <--- PRÜFEN UND ANPASSEN!
// Pfade zu den LLVM-Werkzeugen
CLANG_PATH = 'clang.exe';
LLD_PATH = 'lld-link.exe';
// Pfade zu den LLVM-Werkzeugen (BITTE HIER ANPASSEN!)
CLANG_PATH = 'clang.exe'; // <--- PRÜFEN UND ANPASSEN!
LLD_PATH = 'lld-link.exe'; // <--- PRÜFEN UND ANPASSEN!
type
TMainForm = class( TForm )
WebBrowser1: TWebBrowser;
SaveWorkspaceButton: TSpeedButton;
GenerateCodeButton: TSpeedButton;
Memo: TMemo;
Splitter1: TSplitter;
ToolBar1: TToolBar;
RefreshButton: TSpeedButton;
SaveWorkspaceButton: TSpeedButton;
GenerateCodeButton: TSpeedButton;
InputEdit: TEdit; // <--- Hinzugefügt (Optional für Beschriftung des InputEdit)
procedure FormCreate( Sender: TObject );
procedure FormDestroy( Sender: TObject );
procedure LauchSiteButtonClick( Sender: TObject );
procedure RefreshButtonClick( Sender: TObject );
procedure SaveWorkspaceButtonClick( Sender: TObject );
procedure GenerateCodeButtonClick( Sender: TObject );
procedure WebBrowser1DidFinishLoad( ASender: TObject );
@@ -85,7 +84,8 @@ end;
procedure TMainForm.FormCreate( Sender: TObject );
begin
TLLVMRunner.Log := Memo.Lines;
LauchSiteButtonClick(Self);
// Optional: Standardwert für InputEdit
InputEdit.Text := '123';
end;
procedure TMainForm.FormDestroy( Sender: TObject );
@@ -107,7 +107,7 @@ var
cmdLine: string;
buffer: TBytes;
bytesRead: Cardinal;
output: string;
output, errors: string;
begin
// Pipe für StdOut und StdErr erstellen
sa.nLength := SizeOf( TSecurityAttributes );
@@ -186,7 +186,7 @@ begin
end;
end;
procedure TMainForm.LauchSiteButtonClick( Sender: TObject );
procedure TMainForm.RefreshButtonClick( Sender: TObject );
begin
WebBrowser1.Navigate( PATH_BLOCKLY );
end;
@@ -202,104 +202,122 @@ begin
end;
procedure TMainForm.HandleWebMessage( const AMessage: string );
var
llFile, objFile, dllFile: string;
compilerOutput: string;
success: Boolean;
InputInteger: Integer; // <--- Hinzugefügt
begin
Memo.Lines.Clear;
Memo.Lines.Add( 'LLVM-Code empfangen. Starte Kompilierung...' );
Memo.Lines.Add( AMessage );
Memo.Lines.Add( '--------------------' );
// Wert aus dem InputEdit-Feld holen
try
InputInteger := StrToIntDef( InputEdit.Text, 0 ); // Standardwert 0, falls ungültig
except
InputInteger := 0;
Memo.Lines.Add( 'WARNUNG: Ungültige Eingabe im InputEdit-Feld. Verwende 0.' );
end;
TTask.Run(
procedure
var
llFile, objFile, dllFile: string;
compilerOutput: string;
success: Boolean;
llFileLocal, objFileLocal, dllFileLocal: string; // Lokale Variablen für den Task
compilerOutputLocal: string;
successLocal: Boolean;
begin
llFile := TPath.Combine( TPath.GetTempPath, 'poc.ll' );
objFile := TPath.ChangeExtension( llFile, '.obj' );
dllFile := TPath.ChangeExtension( llFile, '.dll' );
success := False;
llFileLocal := TPath.Combine( TPath.GetTempPath, 'poc.ll' );
objFileLocal := TPath.ChangeExtension( llFileLocal, '.obj' );
dllFileLocal := TPath.ChangeExtension( llFileLocal, '.dll' );
successLocal := False;
try
TFile.WriteAllText( llFile, AMessage );
TFile.WriteAllText( llFileLocal, AMessage );
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( 'Kompiliere zu Objektdatei...' );
end );
compilerOutput := ExecuteProcess( CLANG_PATH, Format( '-c "%s" -o "%s"', [llFile, objFile] ) );
compilerOutputLocal := ExecuteProcess( CLANG_PATH, Format( '-c "%s" -o "%s"', [llFileLocal, objFileLocal] ) );
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( compilerOutput );
Memo.Lines.Add( compilerOutputLocal );
end );
if not TFile.Exists( objFile ) then
if not TFile.Exists( objFileLocal ) then
begin
TThread.Queue( nil,
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( 'FEHLER: Kompilierung fehlgeschlagen. .obj-Datei nicht erstellt.' );
end );
Exit;
Exit;
end;
TThread.Queue( nil,
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( 'Linke zu DLL...' );
end );
compilerOutput := ExecuteProcess( LLD_PATH, Format( '/dll /noentry "%s" /out:"%s"', [objFile, dllFile] ) );
TThread.Queue( nil,
compilerOutputLocal := ExecuteProcess( LLD_PATH, Format( '/dll /noentry "%s" /out:"%s"', [objFileLocal, dllFileLocal] ) );
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( compilerOutput );
Memo.Lines.Add( compilerOutputLocal );
end );
if TFile.Exists( dllFile ) then
if TFile.Exists( dllFileLocal ) then
begin
success := True;
TThread.Queue( nil,
successLocal := True;
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( Format( 'ERFOLG: DLL wurde erstellt: %s', [dllFile] ) );
Memo.Lines.Add( Format( 'ERFOLG: DLL wurde erstellt: %s', [dllFileLocal] ) );
end );
end
else
begin
TThread.Queue( nil,
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( 'FEHLER: Linken fehlgeschlagen. .dll-Datei nicht erstellt.' );
end );
end;
finally
if TFile.Exists( llFile ) then
TFile.Delete( llFile );
if TFile.Exists( objFile ) then
TFile.Delete( objFile );
if not success and TFile.Exists( dllFile ) then
TFile.Delete( dllFile );
finally
if TFile.Exists( llFileLocal ) then
TFile.Delete( llFileLocal );
if TFile.Exists( objFileLocal ) then
TFile.Delete( objFileLocal );
if not successLocal and TFile.Exists( dllFileLocal ) then
TFile.Delete( dllFileLocal );
end;
Memo.Lines.Add( '---------------------------------------------------------' );
Memo.Lines.Add( 'DLL wird aufgerufen:' );
TThread.Queue( nil,
procedure
begin
Memo.Lines.Add( '---------------------------------------------------------' );
Memo.Lines.Add( 'DLL wird aufgerufen:' );
if TFile.Exists( dllFile ) then
begin
var
Runner := TLLVMRunner.Create( dllFile );
try
Runner.Execute;
finally
Runner.Free;
end;
end;
if TFile.Exists( dllFileLocal ) then
begin
var
Runner := TLLVMRunner.Create( dllFileLocal );
try
Runner.Execute( InputInteger ); // <--- HIER DEN INPUT-PARAMETER ÜBERGEBEN
finally
Runner.Free;
end;
end;
Memo.Lines.Add( 'DLL beendet.' );
Memo.CaretPosition := TCaretPosition.Create( Memo.Lines.Count-1, 1 );
end );
end );
Memo.Lines.Add( 'DLL beendet.' );
end;
procedure TMainForm.WebBrowser1DidFinishLoad( ASender: TObject );