![]() |
Funktionszeiger in StringList.Objects speichern und nutzen
Hallo,
Ich würde gerne in einer TStringList per AddObject('SomeStr', @ReadBla); hinzufügen ReadBla ist definiert als function ReadBla(AItem, BItem : Tobject) :boolean. Der Aufruf AddObject wie oben funktioniert nicht. Also Baue ich folgendes TReadMethod = function(A, B : TObject) : boolean of object; dann
Delphi-Quellcode:
Das funktioniert, obwohl ich mir nicht sicher bin ob AMethod wirklich ein Object ist.
var
AMethod : TReadMethod; begin AMethod := ReadBla; AStringList.AddObject('Bla', AMethod); end; Jetzt habe ich das Problem wie rufe ich AMethod aus AStringList auf?
Delphi-Quellcode:
Wenn mir da jemand weiterhelfen könnte wäre das sehr schick.
(AStringList.objects[0] as TReadMethod)(AObject, BObject); //FUNKTIONIERT NICHT!
Gruß |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Mahlzeit!
Warum muss es denn eine TStringList sein? Ist das nicht irgendwie... pervers :) ? Nichts für ungut :stupid: .. |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Sowas geht nicht "direkt", denn function of object ist kein "einfacher" Prozedur-Zeiger, sondern er ist ein Methoden-Zeiger und besteht eigentlich aus 2 Zeigern ala 8 Byte (einmal auf die Funktion und dann nocheiner zum Objekt)
Also paßt er nicht in einen "normalen" 4-Byte-Zeiger rein. Du müßtest dir z.B. mit ![]() |
Re: Funktionszeiger in StringList.Objects speichern und nutz
puh,
schade, nagut dann baue ich ein Object dessen Eigenschaft den Zeiger beinhaltet und packe das dort rein. Thx für die schnellen Antworten |
Re: Funktionszeiger in StringList.Objects speichern und nutz
@himitsu
Hey ich probiere gerade deine Methode über new aus. Also Definiere ich
Delphi-Quellcode:
Wie Rufe ich die ganze Sache jetzt auf?
var
ARead : ^TReadMethod; begin New(ARead); ARead^ := ReadBla; AStringList.AddObject('Bla', ARead); end; TReadMethod(AStringList.Objects[0])^(A,B) funktioniert nicht |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Müsste das nicht so heißen: "TReadMethod(Pointer(AStringList.Objects[0])^)(A,B)" :gruebel:
(Kann´s gerade nicht testen) |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Kann man Methoden überhaupt ohne Objekt aufrufen?
|
Re: Funktionszeiger in StringList.Objects speichern und nutz
Die Methode ReadBla ist innerhalb des Objektes definiert, also existiert ja ein Objekt.
@mleyen ja das könnte vlt funktionieren aber ich sehe gerade das die Zuweisung AStringList.AddObject('Bla', ARead); nicht funktioniet. ARead ist für ihn kein Objekt. Habe ARead nach dem new Beispiel folgendermaßen definiert
Delphi-Quellcode:
TReadMethod = function(A, B : TObject) : boolean of object;
PReadMethod = ^TReadMethod ... var ARead : PReadMethod |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Wieso fügst Du dann nicht das Objekt in die Liste ein statt "mit Gewalt" nur dessen Methode?
|
Re: Funktionszeiger in StringList.Objects speichern und nutz
das Zuweisen das ist schonmal OK
Delphi-Quellcode:
das Auslesen einfach so
var
ARead : PReadMethod; begin New(ARead); ARead^ := ReadBla; AStringList.AddObject('Bla', ARead); end;
Delphi-Quellcode:
Und am Ende nicht das Freigeben (Dispose) vergessen.
PReadMethod(AStringList.Objects[0])^
@DeddyH: wenn er :=ReadBla nutzt, dann wird dieser Code vermutlich direkt in der Klasse ( :=Self.ReadBla ) rumliegen ... also kein Problem :) |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Zitat:
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; |
Re: Funktionszeiger in StringList.Objects speichern und nutz
So: (OOP)
Delphi-Quellcode:
Oder so (QAD):
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);
Delphi-Quellcode:
@uligerhard: Wegen deiner komischen Bezeichner (Rein, Raus) verstehe ich deinen Code nicht. Machst du das immer so?
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); |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Zitat:
|
Re: Funktionszeiger in StringList.Objects speichern und nutz
Zitat:
Zitat:
(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:
|
Re: Funktionszeiger in StringList.Objects speichern und nutz
Zitat:
Zitat:
[/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: |
Re: Funktionszeiger in StringList.Objects speichern und nutz
Zitat:
|
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 19:41 Uhr. |
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