Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Einzelne Bytes in DWORD setzen


ika89 - So 02.08.09 18:27
Titel: Einzelne Bytes in DWORD setzen
hallo leute,

kann mir jemand eine elegantere lösung verraten einzelne Bytes in einem DWORD zu setzen?
meine bisherige ist:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure test();
var b:Byte;
    d:DWORD; 
begin
   d:=0;
   b:=30;

//so setze ich dann z.B. das erste Byte 
   d:=b;

//und so das zweite ...
   d:=b*256;

end;


meine frage ist nun ob es irgendwie in der art geht:

Delphi-Quelltext
1:
2:
d[0]=20;
d[1]=15;


ich hoffe das es jemanden gibt der versteht was ich meine :D


BenBE - So 02.08.09 18:29


Delphi-Quelltext
1:
2:
3:
4:
5:
type TDWORDtoByte = packed record
    case Boolean of
        false: (d: DWORD; );
        true: (b: array[0..3of Byte; );
    end;


ika89 - So 02.08.09 18:53

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
type TDWORDtoByte = packed record
    case Boolean of
        false: (d: DWORD; );
        true: (b: array[0..3of Byte; );
    end;


Danke für die schnelle Antwort, habs ausprobiert und... es gefällt mir ^^ wieder was dazugelernt :idea:

Noch zwei Fragen:
1. Wie bewirkt dieses "case Boolean of" (bzw. wie kommt das zustande), dass die variablen "d" und "b" auf den selben speicher zeigen?
2. Gibt es die Möglichkeit den selben Sachverhalt in folgender Form zu lösen:
für das 1. Byte - die adresse von der DWORD variablen ermitteln und den Byte bei dieser adressse auf einen Wert setzen
für das 2. Byte - die adresse von der DWORD variablen + 1 und das dann auf einen bestimmten wert setzen
für das 3. Byte - die adresse von der DWORD variablen + 2 und das dann auf einen bestimmten wert setzen usw. ?

[edit]
um mich verständlicher zu machen habe ich ein kurzes Beispiel gemacht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
 dw:    DWORD;
 bl:array[0..3]of Byte;
begin
// so zerteilt man ein DWORD oder was auch immer in Bytes:
  b1[0]:=dw shr 0;
  b1[1]:=dw shr 8;
  b1[2]:=dw shr 16;
  b1[3]:=dw shr 24;

// warum funktioniert das nicht auch so rum: ?
  (dw shr 8):=b1[1];


was muss umgestaltet werden?


jaenicke - So 02.08.09 19:07

user profile iconika89 hat folgendes geschrieben Zum zitierten Posting springen:
Gibt es die Möglichkeit den selben Sachverhalt in folgender Form zu lösen:
Genau das macht der variante Record ja. Eben weil beides auf den selben Speicher zugreift. ;-)

Und so wie du es meinst:
Adresse mit @ ermitteln, auf integer casten, um 0, 1, ... erhöhen und auf PByte casten. ;-)
Dann mit xy^ := 4 den Wert schreiben.


ika89 - So 02.08.09 19:16

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconika89 hat folgendes geschrieben Zum zitierten Posting springen:
Gibt es die Möglichkeit den selben Sachverhalt in folgender Form zu lösen:
Genau das macht der variante Record ja. Eben weil beides auf den selben Speicher zugreift. ;-)

Und so wie du es meinst:
Adresse mit @ ermitteln, auf integer casten, um 0, 1, ... erhöhen und auf PByte casten. ;-)
Dann mit xy^ := 4 den Wert schreiben.


danke, du hast die idee erfasst, obwohl die weniger elegant für manche scheinen würde.
ich wede das jetzt mal umsetzen und posten...


jaenicke - So 02.08.09 19:24

user profile iconika89 hat folgendes geschrieben Zum zitierten Posting springen:
danke, du hast die idee erfasst, obwohl die weniger elegant für manche scheinen würde.
Naja, nicht weniger elegant, aber praktisch exakt das selbe nur mit mehr Code eben. :lol:


ika89 - So 02.08.09 19:34

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconika89 hat folgendes geschrieben Zum zitierten Posting springen:
danke, du hast die idee erfasst, obwohl die weniger elegant für manche scheinen würde.
Naja, nicht weniger elegant, aber praktisch exakt das selbe nur mit mehr Code eben. :lol:


nochmal danke jaenicke^^, so sieht das als ein kleiner test aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.FormCreate(Sender: TObject);
var einDWORD:DWORD;
    byte2:Byte;
begin
  einDWORD:=0;

  //damit muss einDWORD der wert 256 annehmen
  byte2:=1;

  //diese codezeile erfreut doch jedes Programmiererherz :))
  PByte(Integer((@einDWORD))+1)^:=byte2;

  Caption:=IntToStr(einDWORD); // Caption zeigt den Wert 256 an^^
end;


freut mich das es funktioniert, Problem gelöst


BenBE - So 02.08.09 19:40


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure EditDWORDBytewise(d:DWORD);
var
    b: packed array[0..3of Byte absolute d;
begin
    b[2] := 3;
end;


jaenicke - So 02.08.09 20:05

Oder:

Delphi-Quelltext
1:
2:
3:
4:
procedure EditDWORDBytewise(var d: DWORD);
begin
  LongRec(d).Bytes[1] := 4;
end;