![]() |
Interface + (Record)Operatoren [MiniMathLib]
Liste der Anhänge anzeigen (Anzahl: 1)
Soooooo, es ist soweit, hier mal mein Versuch Interfaces die Operatoren beizubringen :angel:
Die Operatoren funktionieren erstmal :hello: , aber irgendwo hab ich Probleme mit der Referenz-/Instanz-Zählung, welche ich mir eingebaut hatte, um Speicherlecks und zu finden und vorallem um die Erstellung/Ausnutzung Objekte besser im Überblick zu haben (hatte ja noch nie so direkt mit Interfaces gearbeitet) Am Ende (außerhalb der Testprozedur) sollten alle Zähler wieder auf 0 stehen, was auch für die Hauptzähler stimmt, aber bei den Zählern der SubKlassen stimmt was nicht, die stehen nicht immer auf 0 und angeblich wurde sogar mehr freigegeben als existierte, obwohl deren Summe mit dem Hauptzähler übereinstimmen müßte. Ich bin grad dabei die LogFile (siehe Delphi's Ereignisprotokoll) zu zerlegen, aber da brauch ich noch 'ne Weile. Vielleicht findet ja auch jemand raus, wo der Fehler steckt :love: Wie gesagt, insgesammt scheint die Freigabe zu funktionieren und es wird vermutlich nur irgendwo falsch gezählt. So wie der Testcode jetzt ist, wurden 3 TSmallInt und 5 TSmallFloat zuviel freigegeben, aber wenn das stimmen täte, dann hätt' doch da Destroy; meckern müssen, wenn nicht mehr existierender Speicher freigegeben werden soll? Es geht um die Variablem mit diesem Suchmuster "(_Instances|_References|_AllInstances|_AllReferen ces)" (reguläre Ausdrücke) wär nett, wenn da noch mit jemand reinsehn könnte :angel: PS: nicht wundern, zum Test hab ich mir erstmal nur zwei einfache und funktionierende SmallMathTypen erstellt :angel2: |
Re: Interface + (Record)Operatoren [MiniMathLib]
_AddRef und _Release sollten nur in der Basisklasse TOperatorObject vorhanden sein.
Daher brauchen diese Funktionen auch nicht virtuell zu sein.
Delphi-Quellcode:
TSmallInteger = Class(TOperatorObject)
Protected Function _AddRef: Integer; Override; StdCall; // weg Function _Release: Integer; Override; StdCall; // weg |
Re: Interface + (Record)Operatoren [MiniMathLib]
ich hatte diese beiden Funktionen erst NICHT-virtual ... und auch trat schon der selbe Fehler auf ... hatte es jetzt nur zum Testen mal getrennt. (wird also später wieder entfernt)
Aber ob nur Virtual oder nicht, die Referenzzählung simd so oder so nicht. :? [add] ach ja, ich vergaß zu sagen: - ab Delphi 2006 (wegen der Operatoren) - und wenn man das Programm durchlaufen läßt, dann kommt sollte beim letzen END; der Run-Prozedur alle Instanzen freigegeben werden und die If-Abfrage müßte ohne Exception erfolgen (was sie leider nicht tut)
Delphi-Quellcode:
[add2]
Begin
Run; If GetCounters <> '...' Then Raise Exception.Create('memory leak... Zitat:
|
Re: Interface + (Record)Operatoren [MiniMathLib]
Zitat:
Diese Klasse implementiert _AddRef, _Release und QueryInterface. Diese Methoden sollen und dürfen dann nicht in deinem Sourcecode auftauchen. Die Deklaration deines Interface sieht dann so aus:
Delphi-Quellcode:
Damit hast du die Referenzzählung komplett an die Klasse IInterfacedObject abgegeben.
IOperatorInterface = Interface(IUnknown) // von IUnkown erben
['{36BE8FFE-9DAE-456E-894F-8DBD1520549D}'] // Function QueryInterface(Const IID: TGUID; Out Obj): HResult; StdCall; // wird schon in IUnknown deklariert // Function _AddRef: Integer; StdCall; // Function _Release: Integer; StdCall; Function CreateInstance: IOperatorInterface; Function GetType: TOperatorClass; Function GetObject: TOperatorObject; |
Re: Interface + (Record)Operatoren [MiniMathLib]
Hatte am Anfang mit IInterface (ist in Delphi das Selbe wie IUnknown) und TInterfacedObject (als Basis für meine Grundklasse) gearbeitet, aber gefiehl mir die Referenzzählung nicht so richtig.
Hab aber eben mal NewInstance abgeändert und AfterConstruction eingeführt ... damit isses genauo wie bei TInterfacedObject, aber ändert nichts. Wenn ich komplett umsteige, dann hab ich das Problem mit der komischen Refferenzzählung in den SubKlassen nicht mehr, da dieses dort nicht mehr gezählt werden kann. Abgesehn davon, daß ich dann nicht weiß, ob es da immernoch Probleme gibt, da man sie ja nicht sieht ... nur weil man was nicht sieht, heißt es doch nicht, daß es dieses nicht mehr gibt. :angel2: Ansonsten funktioniert alles, was mit FRefCount zusammenhängt und größtenteils auch dem in TInterfacedObject entspricht, ja ganz gut (das Basisobject steht, wie erwartet, am Ende auf 0:0). [add] ReportMemoryLeaksOnShutdown := True; hab ich auch schon ausprobiert ... es gab keine Meldung, also vermutlich wirklich alles OK :angel: ... bis eben auf die Zählung :? [ot/add2] kraß, mit Debugger braucht die Prozedur RUN ~5 Sekunden ... ich dacht schon meine Verarbeitung ist schuld dran ... ohne Debugger sind's aber nur 31 ms :shock: |
Re: Interface + (Record)Operatoren [MiniMathLib]
ähm, .. interessant .. Interfaces mit Operatoren?
was macht man dann damit? könnte man dann mit dieser etwas seltsam anmutenden Methode auch Operatoren für normal Klassen überladen? hmmmm Darf ich fragen, warum Du nicht normale Records genommen hast, und was Du mit den Interfaces dann antellen willst? Entschuldige die Fragen, seh noch nicht richtig durch, was Du da vor hast :-) |
Re: Interface + (Record)Operatoren [MiniMathLib]
Zitat:
Zitat:
Am Besten läßt ich das wohl für 'ne kleine MathLib verwenden oder man nutzt die Möglichkeiten der impliziten/expliziten Typenumwandlung um einem Interface/Objekt Daten zuzuweisen oder diese abzufragen. Zitat:
Zitat:
![]() aber da isses recht aufwendig dort mehrere Typen miteinander zu verknüpten, da jeder Record ein eigener Datentyp ist ... hier konnt ich alles auf einen Grund-Datentypen reduzieren. bin dadurch hierauf gekommen ... die Neugierde halt :oops: > ![]() Zitat:
aber wenn das funktioniert, kann ich dann leichter an meiner kleinen MathLib weiter rumspielen (aber den nur auf Record basierenden Integer[TBigInt] werd ich wohl dennoch weiterführen, da auch seine Vorteile hat) |
Re: Interface + (Record)Operatoren [MiniMathLib]
komisch, ich bin jetzt die LogFile durch und denmach würde ich denken der müßte richtig zählen, da die Prozeduren, wo gezählt wird, richtig aufgerufen werden ... aber der Zähler sagt ja was anderes :gruebel:
[add] ich hab's gefunden :wall: es lag an Aufrufen wie diesen
Delphi-Quellcode:
den Array wurden zwar nur SubKlassen von TOperatorClass zugewiesen, aber .Create rief nur TOperatorClass.Create direkt auf und nicht das .Create der zugewiesenen SubKlasse ... obwohl dennoch eine Intanz des Subtypes entstand (nur halt ohne dessen .Create zu nutzen :shock: )
Var RegisteredOperatorClasses: packed Array of TOperatorClass;
X := RegisteredOperatorClasses[i].Create; werde das mal abändern und mein Problem sollte gelöst sein :firejump: |
Re: Interface + (Record)Operatoren [MiniMathLib]
Delphi-Quellcode:
hmm .. war das Dein Hauptgrund?
aber da isses recht aufwendig dort mehrere Typen miteinander zu verknüpten, da jeder Record ein eigener Datentyp ist
das ist doch eigenltich einfach ... entweder Du lässt es von der impliziten Typumwandlung erledigen. etwa so dann ...
Delphi-Quellcode:
// Kategorie: Unäre Operatoren
class operator Negative(const AValue: FIXCOMMA64): FIXCOMMA64; class operator Positive(const AValue: FIXCOMMA64): FIXCOMMA64; class operator Trunc(const AValue: FIXCOMMA64): Int64; class operator Round(const AValue: FIXCOMMA64): Int64; class operator Inc(const AValue: FIXCOMMA64): FIXCOMMA64; // class operator Inc(const AValue1, AValue2: FIXCOMMA64): FIXCOMMA64; class operator Dec(const AValue: FIXCOMMA64): FIXCOMMA64; // Kategorie: Binäre Operatoren class operator Add(const Left, Right: FIXCOMMA64): FIXCOMMA64; class operator Subtract(const Left, Right: FIXCOMMA64): FIXCOMMA64; class operator Multiply(const Left, Right: FIXCOMMA64): FIXCOMMA64; class operator Divide(const Left, Right: FIXCOMMA64): FIXCOMMA64; class operator IntDivide(const Left, Right: FIXCOMMA64): FIXCOMMA64; class operator Modulus(const Left, Right: FIXCOMMA64): FIXCOMMA64; // Kategorie: Vergleichsoperatoren class operator Equal(const Left, Right: FIXCOMMA64): Boolean; inline; class operator NotEqual(const Left, Right: FIXCOMMA64): Boolean; inline; class operator LessThan(const Left, Right: FIXCOMMA64): Boolean; inline; class operator LessThanOrEqual(const Left, Right: FIXCOMMA64): Boolean; inline; class operator GreaterThan(const Left, Right: FIXCOMMA64): Boolean; inline; class operator GreaterThanOrEqual(const Left, Right: FIXCOMMA64): Boolean; inline; // Kategorie: implicite Konvertierung class operator Implicit(const AValue: FIXCOMMA64) : FIXCOMMA40; inline; class operator Implicit(const AValue: FIXCOMMA40): FIXCOMMA64; inline; class operator Implicit(const AValue: FIXCOMMA64) : FIXCOMMA32; inline; class operator Implicit(const AValue: FIXCOMMA32): FIXCOMMA64; inline; class operator Implicit(const AValue: FIXCOMMA64) : FIXCOMMA24; inline; class operator Implicit(const AValue: FIXCOMMA24): FIXCOMMA64; inline; class operator Implicit(const AValue: DWORD): FIXCOMMA64;inline; class operator Implicit(const AValue: Integer): FIXCOMMA64; inline; class operator Implicit(const AValue: Int64): FIXCOMMA64; inline; class operator Implicit(const AValue: FIXCOMMA64) : Single;inline; class operator Implicit(const AValue: Single): FIXCOMMA64; inline; class operator Implicit(const AValue: FIXCOMMA64) : double;inline; class operator Implicit(const AValue: double): FIXCOMMA64; inline; class operator Implicit(const AValue: FIXCOMMA64) : extended; inline; class operator Implicit(const AValue: extended): FIXCOMMA64; inline; class operator Implicit(const AValue: FIXCOMMA64) : TFLOAT;inline; class operator Implicit(const AValue: TFLOAT): FIXCOMMA64; inline; class operator Implicit(const AValue: TINT32): FIXCOMMA64; inline; class operator Implicit(const AValue: TDWORD): FIXCOMMA64; inline; class operator Implicit(const AValue: String): FIXCOMMA64; inline; end; // FixComma64 oder aber, Du definierst Dir für jeden Datentyp die Operatiren neu... Für jede Seite .. aber wie gesagt, mit der impliziten Typumwandlung kommt man doch schon recht weit eigentlich?
Delphi-Quellcode:
class operator Add(const Left : Double, Right: FIXCOMMA64): FIXCOMMA32;
class operator Add(const Left : FIXCOMMA64, Right: Double): FIXCOMMA32; |
Re: Interface + (Record)Operatoren [MiniMathLib]
Zitat:
bei meinen Records waren es nur 2 statische und 2 dynamische Typen (was die Datengröße betrifft) und die sollten alle miteinander agieren können, also braucht jeder alle Schnittstellen für sich und die anderen Typen und dazu dann noch die Schnittstellen zu delphis Standardtypen. hier gibt's das nur einmal und ich kann beliebig viele (eigene) Typen einbinden. und ich hab mal was Neues erschaffen ... ein Objekt/Interface mit Operaoren ... sowas hat nich jeder ^^ Mit Hagens DEC werd ich, von der Leistung her nie mithalten können, aber die Bediehnung ist schonmal leichter :mrgreen: Wie gesagt, den Versuch nur mit "einfachen" Records hab ich schon gestartet, aber da gibt es Grenzen, vorallem wenn man mal einen Record ändern/hinzufügen möchte, ist der Aufwand enorm ... bei den Interfaces müssen dagegen nur das eine Objekt und die Converter angepaßt werden :stupid: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 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