![]() |
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
Zitat:
Mavarik |
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
![]() Das geht auch nach dem 10. Bier noch :mrgreen: Zitat:
|
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
Daher habe ich mich mit diesen Funktionen nie beschäftigt. Mavarik |
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
Nach dem Motto AktForm hasImplemented(SetFoo), oder so? |
AW: FormularArray den richtigen Create aufrufen! Wie?
Grundsätzlich meckert der Compilier, wenn man eine Instanz 'ner Klasse erstellen will, wo noch abstrakte Methoden drin sind.
Demnach könnte man sagen, daß es garnicht nötig ist, das zu prüfen. Aber schau mal bei TStream in den Quellcode. Dort gibt es zwei Varianten für Seek (einmal 32 und nochmal für 64 Bit). Dort drin wird geschaut, ob die andere Variante überladen wurde, falls sie selber nicht überladen sind und rufen dann entweder das Andere auf, oder werfen eine Exception. |
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
|
AW: FormularArray den richtigen Create aufrufen! Wie?
Da ja nur der Compiler prüft, kann er nur auf direkte Typen prüfen.
Im laufenden Programm ist es ja nicht verboten ... es gibt halt nur eine Exception, wenn man diese Methoden aufrufen will. Der Code im TStream macht eigentlich nichts Anderes, als die Procedur-Adressen zu vergleichen. Für abstrakte Mtehoden leitet Delphi das auf eine Dummy-Methode um, wo die EAbstract-Exception dann ausgelöst wird. (wäre schöner gewesen, wenn Delphi dort auch noch den Methoden Namen übergeben hätte, damit man auch erfährt wo es knallt). Also der holt sich die Eintrittspunkte einmal aus seiner Instanz, bzw. aus der VMT des Typs, welcher grade der Objektinstanz zugeordnet ist. Und dann noch die Adresse der Vergleichsmethode, direkt aus dem gewünschten Typ, welche dann Beide verglichen werden ... wenn gleich, dann wurde nicht überschrieben. (es sei den jemand trickst, ändert auch die RTTI des Ursprungstypen und verschleiert so die Änderung, aber sowas macht man ja nicht :angel2: ) |
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
Mavarik PS: Gibt es echt kein "hasImplemented(SetFoo)" |
AW: FormularArray den richtigen Create aufrufen! Wie?
Zitat:
Da aber vermutlich alle abstrakten Methoden auf die selbe Methode zeigen, könnte man das damit vergleichen. Man kann über die neue große RTTI gehen und genauer nachsehn was wie wo implementiert ist. Wenn du von beiden Typen eine Instanz hast, dann ganz billig so.
Delphi-Quellcode:
Bei Published-Methoden könnte man auch einfach über
if @Self.MyProc = @Vorfahr.MyProc then // Wobei man hier natürlich noch den Self-Pointer aus dem Vergleich ausschließen muß.
ShowMessage('boom'); // also if TMethod(@Self.MyProc).Code = TMethod(@Vorfahr.MyProc).Code then // OK, und für den Typecast muß alles noch in Variablen kopiert werden. ShowMessage('boom'); ![]()
Delphi-Quellcode:
uses
Rtti; type TTestParent = class procedure VirtualProc; virtual; abstract; procedure AbstractProc; virtual; abstract; published procedure PubVirtualProc; virtual; abstract; procedure PubAbstractProc; virtual; abstract; procedure PubCompareDummy; virtual; abstract; end; TTest = class(TTestParent) procedure VirtualProc; override; published procedure PubVirtualProc; override; end; procedure TTest.VirtualProc; begin end; procedure TTest.PubVirtualProc; begin end; procedure TForm21.FormCreate(Sender: TObject); var TestObj: TTest; ErrorProc: Pointer; Temp1, Temp2: procedure of object; TestC: TClass; begin TestObj := TTest.Create; asm //MOV &ErrorProc, @AbstractError MOV &ErrorProc, OFFSET System.@AbstractError end; //if TestObj.MethodAddress('PubVirtualProc') = @System._AbstractError then if TestObj.MethodAddress('PubVirtualProc') = ErrorProc then ShowMessage('boom 1'); // geht nicht .... wie was das nochmal mit den Adressen im Assembler? //if TestObj.MethodAddress('PubAbstractProc') = @System._AbstractError then if TestObj.MethodAddress('PubAbstractProc') = ErrorProc then ShowMessage('boom 2'); if TestObj.MethodAddress('PubVirtualProc') = TTestParent.MethodAddress('PubVirtualProc') then ShowMessage('boom 3'); if TestObj.MethodAddress('PubAbstractProc') = TTestParent.MethodAddress('PubAbstractProc') then ShowMessage('boom 4'); TestC := TTestParent; Temp1 := TestObj.VirtualProc; Temp2 := TTestParent(@TestC).VirtualProc; if TMethod(Temp1).Code = TMethod(Temp2).Code then ShowMessage('boom 5'); TestC := TTestParent; Temp1 := TestObj.AbstractProc; Temp2 := TTestParent(@TestC).AbstractProc; if TMethod(Temp1).Code = TMethod(Temp2).Code then ShowMessage('boom 6'); TestC := TTestParent; Temp1 := TestObj.VirtualProc; Temp2 := TTestParent(@TestC).VirtualProc; if TMethod(Temp1).Code = TMethod(Temp2).Code then ShowMessage('boom 7'); TestC := TTestParent; Temp1 := TestObj.AbstractProc; Temp2 := TTestParent(@TestC).AbstractProc; if TMethod(Temp1).Code = TMethod(Temp2).Code then ShowMessage('boom 8'); with TRttiContext.Create do begin if GetType(TTest).GetMethod('VirtualProc').CodeAddress = GetType(TTestParent).GetMethod('VirtualProc').CodeAddress then ShowMessage('boom 9'); if GetType(TTest).GetMethod('AbstractProc').CodeAddress = GetType(TTestParent).GetMethod('AbstractProc').CodeAddress then ShowMessage('boom 10'); end; TestObj.VirtualProc; TestObj.PubVirtualProc; TestObj.AbstractProc; TestObj.PubAbstractProc; |
AW: FormularArray den richtigen Create aufrufen! Wie?
Untested!
Delphi-Quellcode:
Mavarik
function MethodIsImplemented(const AClass:TClass;MethodName : string): Boolean;
var m : TRttiMethod; begin Result := False; m:=TRttiContext.Create.GetType(AClass.ClassInfo).GetMethod(MethodName); if m<>nil then Result:=CompareText(AClass.ClassName,m.Parent.Name)=0; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:25 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