Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Problem mit Record-Parametern an MethodenPointer bzw. FunktionsPointer (https://www.delphipraxis.net/208157-problem-mit-record-parametern-methodenpointer-bzw-funktionspointer.html)

himitsu 22. Jun 2021 15:35

AW: Problem mit Record-Parametern an MethodenPointer bzw. FunktionsPointer
 
Zitat:

Zitat von freimatz (Beitrag 1491390)
Ja genau. Einfach "reference to" dazu und Hirn abschalten :-)

Nur beim Vergleichen von Referenzen muß man nachdenken, da beim ReferenceTo intern mit einem "geheimen" Interface gearbeitet wird, wo sich nicht prüfen lässt was da drin für ein Zeiger liegt,

also ein
Delphi-Quellcode:
if meineVariable = @eineFunktion then
geht so nicht mehr, aber Zuweisen oder Ausführen gehen ganz einfach.

Andreas13 24. Jun 2021 12:18

AW: Problem mit Record-Parametern an MethodenPointer bzw. FunktionsPointer
 
Hallo Himitsu,
in den letzten Tagen habe ich nach Deiner Anregung Einiges zu anonymen Methoden gelesen und ausprobiert. Von Deinem Beispiel unter #7 nimmt mein Compiler (10.3 Rio) folgende Zeile nicht an:
Zitat:

Z: reference to function(): Boolean; // alles, inkl. anonymer Methoden (nicht direkt als VAR ... muß einen TYPE haben)
und meldet; E2003 Undeklarierter Bezeichner: 'Reference'. Aber es funktioniert über eine „benannte“ Typendeklaration wie z. B.:
Delphi-Quellcode:
Type
  TMyAnonymus = reference to function(): Boolean;
Var
  z: TMyAnonymus;
Möglicherweise habe ich in meinen Compiler-Optionen etwas falsch eingestellt. Auch die Zeile
Delphi-Quellcode:
L: class of TTest;
kennt mein Compiler (noch) nicht. Aber Deine Anregungen habe ich verstanden und dankend aufgenommen.

Ich habe nun ein Beispiel aus Rolliston: Delphi XE2 Foundations (2012), S. 192-193 konkret auf meinen Anwendungsfall etwas angepaßt:
Delphi-Quellcode:
program Anonymus_Test_2;

{$APPTYPE CONSOLE}

{$R *.res}

Uses
  System.SysUtils;

Type
  DoubleDouble = Record
    X: Array [0 .. 1] of Double;
  End;

Type
  TMyAnonMethod = Reference To Function(CONST Rec: DoubleDouble): DoubleDouble;

Procedure Print(Text: String; CONST Rec: DoubleDouble); overload;
VAR
  S: String;

Begin
  S := Text + Rec.X[0].ToString + ' + ' + Rec.X[1].ToString;
  WriteLn(S);
End;{Print}
{---------}

Function Standalone(CONST Rec: DoubleDouble): DoubleDouble;
Begin
  Print('DoubleDouble-Rec to the standalone function = ', Rec);
End;{Standalone}
{--------------}


Type
  TTest = class
    Function OrdinaryMethod(CONST Rec: DoubleDouble): DoubleDouble;
  End;


Function TTest.OrdinaryMethod(CONST Rec: DoubleDouble): DoubleDouble;
Begin
  Print('DoubleDouble-Rec to the ordinary method = ', Rec);
 End;{TTest.OrdinaryMethod}
 {------------------------}


Procedure TestAssignment;
Var
  Ref1, Ref2, Ref3: TMyAnonMethod;
  Obj: TTest;
  X, Y, Z: DoubleDouble;

Begin
  Ref1:= Standalone;
  Obj := TTest.Create;
  Try
    Ref2:= Obj.OrdinaryMethod;

    Ref3:= Function(CONST Rec: DoubleDouble): DoubleDouble // OHNE Semikolon!!!!!!
           Begin
             Print('DoubleDouble-Rec to the anonymous method = ', Rec);
           End;

     // Aufruf der Funktionen:

     X.X[0] := 1;
     X.X[1] := 11;

     Y.X[0] := 2;
     Y.X[1] := 22;

     Z.X[0] := 3;
     Z.X[1] := 33;


    Ref1(X);
    WriteLn;

    Ref2(Y);
    WriteLn;

    Ref3(Z);
    WriteLn;

  Finally
    Obj.Free;
  End;
End;{TestAssignment}
{------------------}
VAR
  // Global: Reference To Function(CONST Rec: DoubleDouble): DoubleDouble; // ---> E2003 Undeklarierter Bezeichner: 'Reference'

  Ref_Global: TMyAnonMethod;
  T        : DoubleDouble;
  Obj_Global: TTest;

Begin
  Try
    TestAssignment; // ----> Alle Aufrufe funktionieren

    T.X[0] := 4;
    T.X[1] := 44;

    Ref_Global:= Standalone; // ----> funktioniert
    Ref_Global(T);
    WriteLn;

    T.X[0] := 5;
    T.X[1] := 55;

    Obj_Global:= TTest.Create;

    Try
      Ref_Global:= TTest.OrdinaryMethod; // error E2010: E2010 Inkompatible Typen: 'TMyAnonMethod' und 'Procedure'

      Ref_Global(T);
      WriteLn;


      ReadLn;
      Finally
        Obj_Global.Free;
      End;
  Except
    On E: Exception Do
      Writeln(E.ClassName, ': ', E.Message);
  End;
End.
Läßt sich eine anonyme Methode ausschließlich von Objekten (Klassen) heraus aufrufen? So wäre das Nix für mich, denn ich bräuchte die Möglichkeit, diese sowohl aus einer stinknormalen Procedur/Function wie aus Klassen heraus aufrufen zu können, ähnlich wie ProzedurPointer und MethodenPointer. (s. #4 (TiGü) und #5).

Oder habe ich die Idee der anonymen Methoden falsch umgesetzt?

Danke & Gruß Andreas

himitsu 24. Jun 2021 14:11

AW: Problem mit Record-Parametern an MethodenPointer bzw. FunktionsPointer
 
Darum auch erwähnt
Delphi-Quellcode:
// ... (nicht direkt als VAR ... muß einen TYPE haben)
:zwinker:


Zitat:

Delphi-Quellcode:
Ref_Global:= TTest.OrdinaryMethod; // error E2010: E2010 Inkompatible Typen: 'TMyAnonMethod' und 'Procedure'

Eine "Methode" kann nur über ein Objekt genutzt werden, also
Delphi-Quellcode:
Ref_Global := Obj_Global.OrdinaryMethod;
,

aber als "Klassen-Methode" geht es auch direkt über den Typ-Bezeichner.
Delphi-Quellcode:
Type
  TTest = class
    Class Function OrdinaryMethod(CONST Rec: DoubleDouble): DoubleDouble;
  End;

...

Ref_Global := TTest.OrdinaryMethod;

Andreas13 24. Jun 2021 18:42

AW: Problem mit Record-Parametern an MethodenPointer bzw. FunktionsPointer
 
Danke, Himitsu,
Zitat:

Zitat von himitsu (Beitrag 1491484)
Darum auch erwähnt
Delphi-Quellcode:
// ... (nicht direkt als VAR ... muß einen TYPE haben)
:zwinker:

VAR habe ich falsch gedeutet. :oops:
Gruß, Andreas


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:39 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz