Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Di 13.10.09 11:58 
Ich will empfangene Daten parsen. Dazu habe ich z.b. Folgendes:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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).

_________________
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: 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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 18.10.09 14:00 
Es gibt die entsprechenden Records in Delphi bereits...
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: So 18.10.09 15:53 
byte8variable:=byte8(high, low);

und dann halt den explicit operator entsprechend überladen.