Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Funktionszeiger in StringList.Objects speichern und nutzen (https://www.delphipraxis.net/143613-funktionszeiger-stringlist-objects-speichern-und-nutzen.html)

uligerhardt 19. Nov 2009 11:29

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
Zitat:

Zitat von himitsu
@DeddyH: wenn er :=ReadBla nutzt, dann wird dieser Code vermutlich direkt in der Klasse ( :=Self.ReadBla ) rumliegen ... also kein Problem :)

Wenn das so wäre, dann könnte man sich das Gezuchtel mit New und Dispose sparen, und doch nur den 4-Byte-Funktionszeiger (TMethod.Code) verwenden:
Delphi-Quellcode:
  TMyClass = class
  strict private
    FStringList: TStringList;
    function ReadBla(AItem, BItem: TObject): Boolean;
    procedure Rein(const AName: string; const AReadMethod: TReadMethod);
    function Raus(AIndex: Integer; AItem, BItem: TObject): Boolean;
  public
    constructor Create;
    procedure Test;
  end;

constructor TMyClass.Create;
begin
  inherited Create;
  FStringList := TStringList.Create;
end;

procedure TMyClass.Test;
begin
  Rein('Bla', ReadBla);
  if not Raus(0, nil, nil) then
    Beep;
end;

procedure TMyClass.Rein(const AName: string; const AReadMethod: TReadMethod);
var
  AMethod: TMethod;
begin
  TReadMethod(AMethod) := AReadMethod;
  FStringList.AddObject(AName, AMethod.Code);
end;

function TMyClass.Raus(AIndex: Integer; AItem, BItem: TObject): Boolean;
var
  AMethod: TMethod;
begin
  AMethod.Data := Self;
  AMethod.Code := FStringList.Objects[AIndex];
  Result := TReadMethod(AMethod)(AItem, BItem);
end;

alzaimar 19. Nov 2009 13:24

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
So: (OOP)
Delphi-Quellcode:
Type
  TSomeFunction = Function (A,B : TSomeType) : TSomeResult;
  TMetaFunction = Class
  Private
    fFunction : TSomeFunction;
  Public
    Constructor Create (aFunction : TSomeFunction);
    Function CallFunction (A,B : TSomeType) : TSomeResult;
  End;

Constructor TMetaFunction.Create(aFunction : TSomeFunction);
Begin
  fFunction := aFunction;
End;

Function TMetaFunction.CallFunction (A,B : TSomeType) : TSomeResult;
Begin
  Result := fFunction (A,B);
End;
...

  MyFunctions.Add('FooBarFunction', TMetaFunction.Create(@FooBar)); // Muss man nur beim Aufräumen aufpassen.

  MyResult := TMetaFunction(MyFunctions.Objects[MyFunctions.IndexOf('FooBarFunction')]).CallFunction(A,B);
Oder so (QAD):
Delphi-Quellcode:
Var
  FunctionNames : TStringList;
  FunctionPointer : TList;

Procedure AddFunction (aName : String; aFunction : TSomeFunction);
Begin
  FunctionNames.Add(aName);
  FunctionPointer.Add(aFunction);
End;

Function GetFunction (aName : String) : TSomeFunction;
Begin
  Result := TSomeFunction(FunctionPointer[FunctionName.IndexOf(aName)]);
End;
...
AddFunction ('FooBarFunction', @FooBar);
MyResult := GetFunction('FooBarFunction')(A,B);
@uligerhard: Wegen deiner komischen Bezeichner (Rein, Raus) verstehe ich deinen Code nicht. Machst du das immer so?

uligerhardt 19. Nov 2009 13:34

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
Zitat:

Zitat von alzaimar
@uligerhard: Wegen deiner komischen Bezeichner (Rein, Raus) verstehe ich deinen Code nicht. Machst du das immer so?

In "echtem" Code verwende ich natürlich andere Namen. Aber für das Beispiel (Methode rein in die Stringliste, Methode wieder rausholen) erschienen mir Rein/Raus recht aussagekräftig - offensichtlich eine Fehleinschätzung. Andererseits ist der Code ja jetzt wirklich nicht so kompliziert, dass meine "Obfuskation" dir keine Chance zum Durchsteigen lässt.

uligerhardt 19. Nov 2009 13:47

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
Zitat:

Zitat von alzaimar
Delphi-Quellcode:
Type
  TSomeFunction = Function (A,B : TSomeType) : TSomeResult;

Zitat:

Zitat von Master_BB
TReadMethod = function(A, B : TObject) : boolean of object;

Wenn ich nicht was übersehen habe, funktionieren deine Lösungen für den OP nicht, weil er Methodenzeiger speichern will, während du normale Prozedurzeiger nimmst?

(Wobei: Falls die Methoden wirklich nur immer als Self.ReadBla aufgerufen werden, könnte man das Ganze vielleicht so umformulieren, dass das Speichern normaler 4-Byte-Funktionszeiger ausreicht.)

Zitat:

Zitat von alzaimar
Delphi-Quellcode:
Var
  FunctionNames : TStringList;
  FunctionPointer : TList;

Procedure AddFunction (aName : String; aFunction : TSomeFunction);
Begin
  FunctionNames.Add(aName);
  FunctionPointer.Add(aFunction);
End;

Function GetFunction (aName : String) : TSomeFunction;
Begin
  Result := TSomeFunction(FunctionPointer[FunctionName.IndexOf(aName)]);
End;
...
AddFunction ('FooBarFunction', @FooBar);
MyResult := GetFunction('FooBarFunction')(A,B);

Dann kann man die Funktionszeiger doch auch gleich in FunctionNames.Objects stecken.

alzaimar 19. Nov 2009 14:11

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
Zitat:

Zitat von Master_BB
ReadBla ist definiert als function ReadBla(AItem, BItem : Tobject) :boolean.

Zitat:

Zitat von uligerhardt
Wenn ich nicht was übersehen habe, funktionieren deine Lösungen für den OP nicht, weil er Methodenzeiger speichern will, während du normale Prozedurzeiger nimmst?

Auslegungssache. Wenn er wirklich Methodenzeiger möchte, funktioniert die QAD (Quick and Dirty) Lösung nicht. Für die OOP-Lösung muss nur die Deklaration von TSomeFunction geändert werden.
[/quote]Dann kann man die Funktionszeiger doch auch gleich in FunctionNames.Objects stecken.[/quote]
Stimmt. Ich sitze gerade mit JetLag am Nordpazifik, da passiert sowas schon mal. Das ist auch der Grund, wieso ich 'Rein/Raus' nicht kapiert habe, obwohl das sonst eigentlich recht einfach ist. :stupid:

uligerhardt 19. Nov 2009 14:30

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
Zitat:

Zitat von alzaimar
Stimmt. Ich sitze gerade mit JetLag am Nordpazifik

Redmond? :-P

Master_BB 19. Nov 2009 15:00

Re: Funktionszeiger in StringList.Objects speichern und nutz
 
Nachtrag: OOP-Lösung enthält NOCH KEIN FREIGEBEN, dies muß separat geschehen.

Die OOP Lösung habe ich verwendet, wollte das ungetüm nur umgehen.


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

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