![]() |
TypeCasting, Datenübergabe, ...
Ich habe verschiedene 'Daten-Schlangen' in allokierten PByteArray's mit unterschiedlicher Länge.
Diese Array's enthalten jeweils sequenziell verschiedene Datenstrukturen mit wiederum unterschiedlicher Länge. Jede Datenstruktur hat am Anfang einen TAG/Typ und dessen Länge, so dass ich jeweilige 'Blöcke' entsprechend herauslesen und interpretieren kann. Das funktioniert auch so weit sehr gut, so lange ich mich in der Prozedur befinde, welche das allokierte Array übergeben bekommt. Ich werte immer den TAG/Typ aus, lese die Daten entsprechend in meine Strukturen und 'hüpfe' dann zum nächsten TAG/Typ, bis das Array komplett gelesen ist. Da es zig TAGs/Typen gibt / geben kann / geben wird, möchte ich gern die Auswertung in eine separate Unit verlagern, welche bei Zeiten problemlos erweitert und 'universell' Daten verarbeiten kann. Soll heissen: Ich möchte den Zeiger auf der aktuellen Position im 'Schlangen-Array' übergeben und die Funtkion soll dann folgendes machen: - Übergabe eines Zeigers (var Data : pointer), ab dem folgende Daten zur Verfügung stehen: - Data[0] ist der TAG/Typ, was zu verarbeiten ist. (Byte) - Data[1] ist die Länge/Anzahl der zu verarbeitenden Daten - Data[x..y] die Daten die ich auswerten / speichern möchte - Rückgabe: Anzahl zu überspringender Bytes in 'Daten-Schlange' für den nächsten Aufruf (Data[1] + 1) Eigentlich ganz einfach ?! ... ... aber irgendwie habe ich Probleme mit der Übergabe des Zeigers in den jeweiligen 'Daten-Schlangen' und dito Übernahme desselben in der Auswerte-Funktion. TypeCast-Fehler oder nur 'dummes Zeug' im Ergebnis. In der aktuellen Routine lese ich alles perferkt - aber in der externen Funktion, hier kommt nur Müll zurück. Kann mir bitte jemand den / die entscheiden Tipp(s) geben .... Bitte ... |
Re: TypeCasting, Datenübergabe, ...
Verwende OOP.
Finde die Gemeinsamkeiten der einzelnen Blöcke (wenn es welche gibt) Erstelle eine Basisklasse.
Delphi-Quellcode:
Leite alle TAG-Klassen (also Klassen, die genau einen Blocktyp verarbeiten) von der Basisklasse ab.
Type
TAbstractTAGClass = Class public Procedure Read (Data : TStreamData); Virtual; Abstract; Class Function TAG : Integer; Virtual; Abstract; End;
Delphi-Quellcode:
Jede TAG-Klasse liest genau einen Blocktyp ein und stellt den Inhalt als Eigenschaften zur Verfügung.
Type
TMyTagClass = Class (TAbstractTAGClass) public Procedure Read (Data : TStreamData); Override; Class Function TAG : Integer; Override; End; Procedure TMyTagClass.Read(Data : TStreamData); Begin // Diese Klasse liest ein Byte und einen Integer-Wert fMyByte := Data.ReadByte; fMyInteger := Data.ReadInteger; ... End; Class Function TMyTagClass.TAG : Integer; Begin // diese Klasse wird durch den TAG '1' im Byte-Array gekennzeichnet Result := 1; End; Erstelle eine Classfactory, die die entsprechende Klasse anhand des gelesenen TAGs liefert. Diese ClassFactory ist eine sehr einfache Klasse. Sie verwaltet eine Liste von Tag/Klassen-Paaren.
Delphi-Quellcode:
Alle deine TAG-Klassen registrieren sich bei dieser Classfactory.
Type
TClassFactory = Class fClasses : TClassList; Public Constructor Create; Procedure RegisterTagClass (aTagClass : TAbstractTAGClass); Function GetClassByTag (aTag : Integer) : TAbstractTAGClass; End; ... Function TClassFactory.RegisterClass (aTagClass : TAbstractTAGClass); Begin fClasses.Add(aTagClass) End; Function TClassFactory.GetClassByTag (aTag : Integer) : TAbstractTAGClass; Begin For Result in fClasses do if Result.TAG = aTAG Then Exit; Result := nil End;
Delphi-Quellcode:
Immer wenn ein neuer TAG-Typ eingeführt wird, leitest du eine entsprechende Klasse von TAbstractTAGClass ab und registrierst diese Klasse in der ClassFactory.
...
ClassFactory.RegisterClass(TMyTAGClass); ClassFactory.RegisterClass(TMyOtherTAGClass); ... Schau mal, wie simpel die Leseroutine ist. Du wirst sie nie wieder anfassen müssen:
Delphi-Quellcode:
Der Kernpunkt ist diese Klassenfabrik, die dir für den TAG-Header die richtige Klasse zum Lesen der folgenden Daten liefert.
...
While not Data.EndReached Do Begin Tag := Data.ReadTag; DataObject := ClassFactory.GetClassByTag(Tag).Create; DataObject.Read(Data); // Was immer du mit den Daten anstellen willst, tu es hier // Du kannst die Objekte in eine Liste packen, dann hättest du deine Daten interpretiert // Oder du implementierst in den Klassen eine eigene 'Execute'-Methode. Die rufst Du hier auf // // DataObject.Execute; // // Vielleicht wieder freigeben. End; So. Das ist skalierbar bis zum geht-nicht-mehr. Du wirst Dir eventuell die 'GetClassByTag'-Methode vorknöpfen müssen, wenn du zu viele Klassen hast und Performance eine große Rolle spielt: Das Suchen der Klasse mit dem richtigen Tag ist ja nur beispielhaft implementiert (Stichwort: Sortierte Liste, Hashmap o.ä). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:02 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