Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - 64Bit Wert zerlegbar speichern


Flamefire - Di 13.10.09 11:58
Titel: 64Bit Wert zerlegbar speichern
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 - Di 13.10.09 12:14

Einzeln: packed array[0..7of 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).


Lossy eX - 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.


Muck - 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 - Mi 14.10.09 12:58

user profile iconMuck hat folgendes geschrieben Zum zitierten Posting springen:
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));                    


Boldar - 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..3of 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 - 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 - 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 - So 18.10.09 15:53

byte8variable:=byte8(high, low);

und dann halt den explicit operator entsprechend überladen.