Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Di 13.10.09 11:58
Ich will empfangene Daten parsen. Dazu habe ich z.b. Folgendes:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| byte8=packed record case Boolean of true:(High,Low:Cardinal); false:(Full:Int64); end; TPacket = packed record case flag:byte of $E:(unused:byte8;) end; |
in dem fall also einen 8-byte wert, von dem ich auf die einzelteile zugreifen will, und das noch übersichtlich sein soll (TRect macht ja das gleiche)
jetzt aber eine frage:gibt es schon einen typ, der das gleiche macht?
würde das so funktionieren, wenn ich mittels Move() speicher aus einem bytearray in eine TPacket variable verschiebe?
da war doch was mit records, dass die nur pointer sind oder so. kanns aber nicht mehr finden wo ich das gelesen hatte.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 13.10.09 12:14
Einzeln: packed array[0..7] of byte; vs. Gesamt: Int64;
Was du mit den Pointern sicherlich meinst sind Ansi\WideStrings ... Records an sich liegen so wie deklariert im Speicher (zzgl. ein wenig Alignment, was man mit packed aber abschalten kann).
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Di 13.10.09 12:53
Durch das Case sogst du ja dafür, dass die Speicherbereiche übereinander liegen. Entsprechend könntest du das Case in byte8 auch erweitern. Kein Case boolean sondern ein Case integer. Dann machste du zusätzlich zu Int64, 2x Cardinal noch das dazu was du haben willst. So wird das auch in dem Int64Rec gemacht. Nur, dass man dabei kein Int64 mehr direkt dabei hätte. Müsste man Casten. Sollte wohl gehen.
Was das Move angeht. Kommt da natürlich darauf an ob du typen benutzt die selber Pointer sind. Also LongStrings und dynamische Arrays. Klassen kommen wohl eher nicht vor. Wenn du nur Strings mit fixer Länge, Statische Arrays, Ordinale Werte benutzt, dann sollte es keine Probleme machen. Ein Record in einem Record wird auch direkt ersetzt. Also das Record wird direkt in das Record eingebettet. Ergo kein Pointer = keine Probleme mit Move.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Muck
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: Di 13.10.09 15:54
Hi,
wenn ich in der Vergangenheit 64 Bit Werte zerlegen musste habe ich das immer mit "absolute" erledigt, anstatt bytes zu moven.
Quelltext 1: 2: 3: 4: 5:
| var X:Int64; XC:Array[0..1] of Cardinal absolute X; XW:Array[0..3] of Word absolute X; XB:Array[0..7] of Byte absolute X; |
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mi 14.10.09 12:58
Muck hat folgendes geschrieben : | wenn ich in der Vergangenheit 64 Bit Werte zerlegen musste habe ich das immer mit "absolute" erledigt, anstatt bytes zu moven. |
"in der Vergangenheit" ist der springende Punkt... diese Methode soll man schon seit Jahr(zehnt?)en nicht mehr benutzen.
Variante Teile in Case-Records sind da schon Mittel der Wahl.
Worauf du mit den Pointern hinauswillst ist mir aber auch nicht klar... Move-Vorgehensweise wäre dann:
Delphi-Quelltext 1:
| Move(@Buffer[cnt], @MyPacket, sizeof(MyPacket)); |
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: So 18.10.09 12:55
Kann man nicht auch einen normalen record nehmen, meinetwegen als
array [0..3] of byte
und dann die Operatoren für implizites Typcasten überladen?
Das ist doch die einfachste und intuitivste Version, falls die Delphiversion neu genug für Operatoren überladen ist.
Also etwa so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| const low = 0; const high = 1; type Tbarray = array [0..3] of byte; type Tcarray = array [low..high] of cardinal; Type Tbyte8=record data: tbarray; class operator implicit(avalue:TByte8): TBarray; class operator implicit(avalue:TByte8): Tcarray; class operator implicit(alavue:TBarray):Tbyte8; class operator implicit(avalue:TCarray):Tbyte8; end;
TByte8.implicit(avalue:TByte8): TBarray; begin ... end; |
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 18.10.09 14:00
Es gibt die entsprechenden Records in Delphi bereits... Delphi-Quelltext 1: 2: 3: 4: 5:
| var MyInt64Value: Int64; begin Int64Rec(MyInt64Value).Words[0] := 3; ... | Und so weiter, ebenso gibt es LongRec und WordRec.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: So 18.10.09 15:17
das mit dem operatoren überladen bringt mich zu einer ähnlichen frage:
ich hätte in dem record gerne sowas benutzt wie:
byte8:=high(+)low;
also dass er mir dann automatisch die 2 werte in die positionen reinsetzt. müsste ja ähnlich gehn. nur wie?
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: So 18.10.09 15:53
byte8variable:=byte8(high, low);
und dann halt den explicit operator entsprechend überladen.
|
|