RTTI Zugriff auf Funktion

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
PascalDragon
Beiträge: 992
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: RTTI Zugriff auf Funktion

Beitrag von PascalDragon »

fliegermichl hat geschrieben: Mi 1. Okt 2025, 12:57 So geht's

Code: Alles auswählen

type
  TBoolMethod = function : boolean of Object;
var
  p : Pointer;
  BoolMethod : TBoolMethod absolute p;

procedure TForm1.Button1Click(Sender: TObject);
var b : boolean;
begin
  p := Form2.MethodAddress('BoolHallo');
  TMethod(BoolMethod).code:= p;
  TMethod(BoolMethod).data:=form2;
  b := BoolMethod();
  if (b) then
    showmessage('ja')
  else
    showmessage('nein');
end;
Warum bitte machst du da einen Umweg über eine globale Variable?! :shock: Und noch dazu mit absolute?! :shock: :shock: Pointer und Methodenzeiger haben unterschiedliche Größe! Du überschreibst durch das Setzen von TMethod.Data komplett andere Daten!
Deklarier einfach eine lokale Variable vom Typ TBoolMethod in deiner Methode und arbeite mit der.
FPC Compiler Entwickler

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1694
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: RTTI Zugriff auf Funktion

Beitrag von fliegermichl »

PascalDragon hat geschrieben: Mo 6. Okt 2025, 15:17
fliegermichl hat geschrieben: Mi 1. Okt 2025, 12:57 So geht's

Code: Alles auswählen

type
  TBoolMethod = function : boolean of Object;
var
  p : Pointer;
  BoolMethod : TBoolMethod absolute p;

procedure TForm1.Button1Click(Sender: TObject);
var b : boolean;
begin
  p := Form2.MethodAddress('BoolHallo');
  TMethod(BoolMethod).code:= p;
  TMethod(BoolMethod).data:=form2;
  b := BoolMethod();
  if (b) then
    showmessage('ja')
  else
    showmessage('nein');
end;
Warum bitte machst du da einen Umweg über eine globale Variable?! :shock: Und noch dazu mit absolute?! :shock: :shock: Pointer und Methodenzeiger haben unterschiedliche Größe! Du überschreibst durch das Setzen von TMethod.Data komplett andere Daten!
Deklarier einfach eine lokale Variable vom Typ TBoolMethod in deiner Methode und arbeite mit der.
Das hatte ich zunächst versucht, aber nicht hinbekommen.
So funktioniert es jetzt bei mir.

Code: Alles auswählen

type
  TBoolMethod = function : boolean of Object;

procedure TForm1.Button1Click(Sender: TObject);
var b : boolean;
    BoolMethod : TBoolMethod;
    p : Pointer;
    M : TMethod;
begin
  p := Form2.MethodAddress('BoolHallo');
  M.code:= p;
  M.data:=form2;
  BoolMethod := TBoolMethod(M);
  b := BoolMethod();
  if (b) then
    showmessage('ja')
  else
    showmessage('nein');

end;

PascalDragon
Beiträge: 992
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: RTTI Zugriff auf Funktion

Beitrag von PascalDragon »

Hier als ganz einfaches Beispiel, wie es funktioniert:

Code: Alles auswählen

program tmethodptr;

{$mode objfpc}

type
  {$M+}
  TTest = class
  published
    function BoolFunc: Boolean;
  private
    fBool: Boolean;
  public
    procedure Test;
  end;

type
  TBoolFunc = function: Boolean of object;

function TTest.BoolFunc: Boolean;
begin
  Result := fBool;
end;

procedure TTest.Test;
var
  b: TBoolFunc;
begin
  TMethod(b).Code := MethodAddress('BoolFunc');
  TMethod(b).Data := Self;
  
  fBool := False;
  Writeln(b());
  fBool := True;
  Writeln(b());
end;

var
  t: TTest;
begin
  t := TTest.Create;
  t.Test;
end.
FPC Compiler Entwickler

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1694
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: RTTI Zugriff auf Funktion

Beitrag von fliegermichl »

Cool, so funktioniert es auch mit Methoden, welche Parameter brauchen.
Hier ein Beispiel:

Die Direktive $M+ ist notwendig, damit einfache Klassen published Properties haben können.

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}{$M+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TMyClass }

  TMyClass = class
  published
    function StringTest(s : string) : string;
  end;


  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    myClass : TMyClass;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TMyClass }

function TMyClass.StringTest(s: string): string;
begin
  Result := 'Vortext ' + s + ' Nachtext';
end;

{ TForm1 }

type
  TStringMethod = function (s : string) : string of object;

procedure TForm1.Button1Click(Sender: TObject);
var M : TStringMethod;
begin
  TMethod(M).Code := myClass.MethodAddress('StringTest');
  TMethod(M).Data := myClass;
  ShowMessage(M('Hallo ein Text'));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  myClass := TMyClass.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  myClass.Free;
end;

end.

Antworten