Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Cardinal in Bytes speichern (https://www.delphipraxis.net/123099-cardinal-bytes-speichern.html)

xZise 27. Okt 2008 18:05


Cardinal in Bytes speichern
 
Hallo ihr,

ich habe folgendes "Problem". Und zwar läuft eine Verbindung zwischen zwei Punkten mithilfe von Bytearrays ab. Bisher hat das gereicht, aber jetzt will ich den ErrCode übertragen. Aber wie macht man das? Der ist ja 4 Byte lang. Und ich hätte dann 6 Bytes zur Verfügung wo der Cardinal in den letzt 4 gespeichert wird.

MfG
xZise

turboPASCAL 27. Okt 2008 18:40

Re: Cardinal in Bytes speichern
 
Schlecht zu beantworten, wie ist denn der ErrorCode definiert bzw. wie gross kann der enthaltene Wert werden ?

Cardinal = 8 Byte bzw. 32 Bit

das heisst du breutest 2 mal 6 Bytes zur die du zur Verfügung hast um ein 8 Byte-Wert zu übertragen.

xZise 27. Okt 2008 18:42

Re: Cardinal in Bytes speichern
 
Also ich habe mit der Codevervollständigung geguckt und diese gibt mir halt Cardinal an. Bzw. im Code ist es als DWord definiert was ja ein Cardinal auch ist.

MfG
xZise

jfheins 27. Okt 2008 18:44

Re: Cardinal in Bytes speichern
 
Genau. DWord (32bit = 4 Bytes) und nicht 8 Bytes :mrgreen:

Schau dir mal variante records an, damit kannst du den Cardinal als Bytearray ansprechen und umgekehrt - falls es das ist, was du willst :gruebel:

turboPASCAL 27. Okt 2008 18:47

Re: Cardinal in Bytes speichern
 
Zitat:

Zitat von jfheins
Genau. DWord (32bit = 4 Bytes) und nicht 8 Bytes :mrgreen:

Klar. :wall: ( Ich Schussel )

xZise 27. Okt 2008 21:08

Re: Cardinal in Bytes speichern
 
Naja meine Frage ist einfach wie kriege ich die da am einfachsten rein.

Einfach das?
Delphi-Quellcode:
for i := 0 to 3 do
  b[i + 2] := ErrCode div Power(255, i);
Ich dachte das man einfach die Bits über das Array schiebt:
Code:
Array: 01010101 01010101 10011001 01100110 10100101 11000110
-------- Head ---------- ---------------Data----------------
                             ^        ^        ^       ^
Cardinal:               10011001 01100110 10100101 11000110
Sozusagen setzte die 32 bits des Cardinals in die Byteschlange des Arrays ab dem 16. / 17. Bit.

MfG
xZise

jfheins 27. Okt 2008 21:15

Re: Cardinal in Bytes speichern
 
Ich finde das heir wesenlich einfacher:
Delphi-Quellcode:
type
  Foo = record
    case Integer of
      0: (arr: array[0..5] of Byte);
      1: (
           dummy1: Word;
           Wert: Cardinal;
         );
  end;
Dann einfach in Wert deinen Cardinalwert reinschrieben, und du kannst ihn in arr als Bytearray wieder rausholen ;)

uligerhardt 27. Okt 2008 21:16

Re: Cardinal in Bytes speichern
 
Ungetestet:
Delphi-Quellcode:
for i := 0 to 3 do
  b[i + 2] := LongRec(ErrCode).Bytes[i];
Uli.

Hawkeye219 27. Okt 2008 21:20

Re: Cardinal in Bytes speichern
 
Hallo,

ohne das Schlüsselwort "packed" könnte die Lösung mit dem varianten Record aber ins Auge gehen...

Gruß Hawkeye

xZise 27. Okt 2008 21:42

Re: Cardinal in Bytes speichern
 
Zitat:

Zitat von jfheins
Ich finde das heir wesenlich einfacher:
Delphi-Quellcode:
type
  Foo = record
    case Integer of
      0: (arr: array[0..5] of Byte);
      1: (
           dummy1: Word;
           Wert: Cardinal;
         );
  end;
Dann einfach in Wert deinen Cardinalwert reinschrieben, und du kannst ihn in arr als Bytearray wieder rausholen ;)

Wie stellst du dir das vor?


Zitat:

Zitat von Hawkeye219
Hallo,

ohne das Schlüsselwort "packed" könnte die Lösung mit dem varianten Record aber ins Auge gehen...

Gruß Hawkeye

Naja noch ist er das nicht.

MfG
xZise

Neutral General 27. Okt 2008 22:28

Re: Cardinal in Bytes speichern
 
Zitat:

Zitat von xZise
Wie stellst du dir das vor?

Naja so:


Delphi-Quellcode:
type
  TFoo = packed record
    case Integer of
      0: (arr: array[0..5] of Byte);
      1: (
           dummy1: Word;
           Wert: Cardinal;
         );
  end;

var foo: TFoo;
    i: Integer;
begin
  // foo füllen
  for i:= 0 to 5 do
    foo.arr[i] := random(256); // ka.. deine daten halt
  // Du willst jetzt nur den Errorcode?
  // ==>
  // Der steht in foot.Wert:
  Send(foo.Wert);
end;
Oder eben umgekehrt. In den Cardinal schreiben und die Bytes auslesen. Die 6 Bytes und der 1. Word + der Cardinal belegen den gleichen Speicher:

Code:
-----------------------------------------------------
| Byte1 | Byte2 | Byte3 | Byte4 | | Byte5 | | Byte6 |
------------------------------------------------------
|    dummy1     |       W     e     r     t     |
------------------------------------------------------

x000x 27. Okt 2008 23:40

Re: Cardinal in Bytes speichern
 
Moin moin,

eine weitere Möglichkeit wäre noch der Weg über Pointer:
Delphi-Quellcode:
//...
var
   Arr : Array[0..5] of Byte;
   P   : PCardinal;
   Wert : Cardinal;
begin
   Wert := 4294967295;
   //Cardinal in Array scheiben
   P := @Arr[2];
   P^:= Wert;
   // und wieder auslesen
   // Little Endian
   //WertNeu := (Arr[5] shl 24) or (Arr[4] shl 16) or (Arr[3] shl 8) or Arr[2];
   xxx := PCardinal(@Arr[2])^;
//...

//...
   // bzw gleich so
   PCardinal(@Arr[2])^ := 4294967295;
   // und auslesen halt wieder
   xxx := PCardinal(@Arr[2])^;

xZise 28. Okt 2008 17:04

Re: Cardinal in Bytes speichern
 
Zitat:

Zitat von x000x
Moin moin,

eine weitere Möglichkeit wäre noch der Weg über Pointer:
Delphi-Quellcode:
//...
var
   Arr : Array[0..5] of Byte;
   P   : PCardinal;
   Wert : Cardinal;
begin
   Wert := 4294967295;
   //Cardinal in Array scheiben
   P := @Arr[2];
   P^:= Wert;
   // und wieder auslesen
   // Little Endian
   //WertNeu := (Arr[5] shl 24) or (Arr[4] shl 16) or (Arr[3] shl 8) or Arr[2];
   xxx := PCardinal(@Arr[2])^;
//...

//...
   // bzw gleich so
   PCardinal(@Arr[2])^ := 4294967295;
   // und auslesen halt wieder
   xxx := PCardinal(@Arr[2])^;

An sowas dachte ich halt ;) Ich schreibe mal eine Demoapplikation.

MfG
xZise

Cyf 28. Okt 2008 17:10

Re: Cardinal in Bytes speichern
 
Zitat:

Zitat von Hawkeye219
Hallo,

ohne das Schlüsselwort "packed" könnte die Lösung mit dem varianten Record aber ins Auge gehen...

Gruß Hawkeye

Wird das eigentlich von Delphi noch unterstüzt? Hab da was im Kopf, aber kann möglicherweise zu einem ganz anderen Thema gewesen sein. :oops:

x000x 28. Okt 2008 17:16

Re: Cardinal in Bytes speichern
 
Moin moin,

wie gesagt, dass war nur eine weitere Möglichkeit. Ich persönlich würde die Variante von jfheins
auch bevorzugen.

Cyf 28. Okt 2008 17:31

Re: Cardinal in Bytes speichern
 
Habs grad mal getestet, scheint noch zu funktionieren, entschuldigt die unnötige Verwirrung :stupid:
Delphi-Quellcode:
  TA = record
    AByte: Byte;
    BInt: Integer;
  end;
  TB = packed record
    AByte: Byte;
    BInt: Integer;
  end;
TA: 8 Bytes
TB: 5 Bytes


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:35 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