Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi [erledigt] Little-Endian-DWord zu Integer und zurück (https://www.delphipraxis.net/119802-%5Berledigt%5D-little-endian-dword-zu-integer-und-zurueck.html)

mOfl 1. Sep 2008 07:16


[erledigt] Little-Endian-DWord zu Integer und zurück
 
(Delphi 7 Personal)

Hallo Jungens,

für ein Programm, das sich aus einem MemoryStream Größen holt, die da als Dwords im Little-Endian-Format stehen, habe ich nach einer Möglichkeit gesucht, die 4 Bytes, sobald sie in meinen Byte-Array-Puffer geladen wurden, in Integer umzuwandeln, um damit arbeiten zu können. Von Assembler wollte und will ich gänzlich die Finger lassen, weil ich keinen Schimmer davon habe. Offensichtlich ist es mit Pointern nicht anders, denn ich fand diese simple Lösung für mein Problem...

Delphi-Quellcode:
buffer: Array[0..3] of Byte;
groesse: integer;
Delphi-Quellcode:
groesse := PInteger(@buffer[0])^;
... die ich nicht verstehe :? Ich habe das an einem schlichten Programm getestet und es scheint wunderbar zu funktionieren, wenn ich von Hand in das Array etwas eintrage, etwa

Delphi-Quellcode:
buffer[0] := $FE;
buffer[1] := $E2;
buffer[2] := $00;
buffer[3] := $00;
dann wird das richtig umgewandelt in die Integer 58110, da es hexadezimal ja E2FE ist, ich verstehe aber nicht, was in dieser kleinen Zeile alles drin steckt. Dass PInteger ein Pointer auf Integerzahlen ist und die grobe Funktion von @ und ^ konnte ich auf einschlägigen Seiten lesen, aber wie funktioniert das zum Beispiel, dass trotz des Aufrufs von Index 0 des Arrays die ganze Zahl umgewandelt wird? Denkt die Funktion mit? =)

Die zweite Sache ist nämlich die, dass ich bestimmte Bytes verändern und dann wieder in den MemoryStream schicken möchte, und das heißt für mich: Integer bearbeiten, wieder in Little-Endian-Form bringen, in ein Byte-Array schreiben und mittels stream.WriteBuffer(buffer, 4) den entsprechenden Wert im MemoryStream überschreiben. Zusätzlich zur allgemeinen Frage also noch die Frage: Wie sieht der äußert raffinierte Befehl rückwärts aus, also von Integer zu Byte-Array oder viel primitiver gefragt - geht das überhaupt so einfach?

Würde mich über fachmännische Hilfe sehr freuen! =)

Grüßle
Dani

PS: Ich bin mir sicher, dass die Delphi Hilfe da ein paar schlaue Sachen bereit hält, aber Windows Vista meint irgendwie, alte Hilfedateien nicht mehr anzeigen zu müssen :(

DeddyH 1. Sep 2008 07:28

Re: Little-Endian-DWord zu Integer und zurück
 
Zitat:

Delphi-Quellcode:
groesse := PInteger(@buffer[0])^;

buffer[0] - Erstes Element des Array
@buffer[0] - Adresse dieses ersten Elementes
PInteger(@buffer[0]) - Es handelt sich um einen Zeiger auf Integer
PInteger(@buffer[0])^ - Wir sind nicht an dem Zeiger interessiert, sondern an den dahinterliegenden Daten (Dereferenzierung)

Ich hoffe, das bringt etwas mehr Klarheit.

BUG 1. Sep 2008 13:00

Re: Little-Endian-DWord zu Integer und zurück
 
Zitat:

Zitat von mOfl
PS: Ich bin mir sicher, dass die Delphi Hilfe da ein paar schlaue Sachen bereit hält, aber Windows Vista meint irgendwie, alte Hilfedateien nicht mehr anzeigen zu müssen :(

Das Programm zum Anzeigen der alten Hilfe-Dateien kann man sich bei MS herunterladen. Google mal nach dem Problem, da müsstest du was finden.

MfG,
Bug

x000x 1. Sep 2008 15:06

Re: Little-Endian-DWord zu Integer und zurück
 
Moin moin,
Zitat:

Zitat von mOfl
...Zusätzlich zur allgemeinen Frage also noch die Frage: Wie sieht der äußert raffinierte Befehl rückwärts aus, also von Integer zu Byte-Array oder viel primitiver gefragt - geht das
überhaupt so einfach?...

Ja, es geht genau so einfach:
Delphi-Quellcode:
//..
   groesse := 439041101;
   PInteger(@buffer[0])^ := groesse;
//..
Ein Integer "besteht" ja aus 4 Bytes (SizeOf(Integer) = 4), es ist also - aus sicht des PCs - das gleiche wie ein Array[0..3] of Byte.
Ein PInteger zeigt auf das erste Byte von den 4 Bytes eines Integers. @buffer[0] zeigt ebenfalls auf das erste Byte unseres Arrays.
Wenn wir jetzt dem Compiler mitteilen, das @buffer[0] ein PInteger ist, können wir diesen ganz einfach dereferenzieren und einen Wert
zuweisen.

Was ich bei dir nur nicht verstehe, warum musst du überhaupt den Weg über ein Array[0..3] of Byte gehen? Du kannst die Werte doch direkt in einen
Integer einlesen?

BUG 1. Sep 2008 15:16

Re: Little-Endian-DWord zu Integer und zurück
 
Zitat:

Zitat von x000x
Was ich bei dir nur nicht verstehe, warum musst du überhaupt den Weg über ein Array[0..3] of Byte gehen? Du kannst die Werte doch direkt in einen

Integer einlesen?

Das könnten auch das Problem sein: der PC benutzt Little-Endian (siehe hier).
Wenn du denn Wert vor dem "in den Integer schreiben" in Big-Endian umsortierst, kommt nur Grütze heraus.

MfG,
Bug

x000x 1. Sep 2008 15:22

Re: Little-Endian-DWord zu Integer und zurück
 
Moin moin,
Zitat:

Zitat von BUG
...Wenn du denn Wert vor dem "in den Integer schreiben" in Big-Endian umsortierst, kommt nur Grütze heraus...

Davon hat er aber nix geschrieben.
Zitat:

Zitat von mOfl
...für ein Programm, das sich aus einem MemoryStream Größen holt, die da als Dwords im Little-Endian-Format stehen, habe ich nach einer Möglichkeit gesucht, die 4 Bytes, sobald sie in meinen Byte-Array-Puffer geladen wurden, in Integer umzuwandeln, um damit arbeiten zu können...


mOfl 1. Sep 2008 17:08

Re: Little-Endian-DWord zu Integer und zurück
 
Zitat:

Zitat von x000x
Moin moin,
Ja, es geht genau so einfach:
Delphi-Quellcode:
//..
   groesse := 439041101;
   PInteger(@buffer[0])^ := groesse;
//..
Ein Integer "besteht" ja aus 4 Bytes (SizeOf(Integer) = 4), es ist also - aus sicht des PCs - das gleiche wie ein Array[0..3] of Byte.
Ein PInteger zeigt auf das erste Byte von den 4 Bytes eines Integers. @buffer[0] zeigt ebenfalls auf das erste Byte unseres Arrays.
Wenn wir jetzt dem Compiler mitteilen, das @buffer[0] ein PInteger ist, können wir diesen ganz einfach dereferenzieren und einen Wert
zuweisen.

Was ich bei dir nur nicht verstehe, warum musst du überhaupt den Weg über ein Array[0..3] of Byte gehen? Du kannst die Werte doch direkt in einen
Integer einlesen?

Vielen Dank für die erleuchtende und weiterbringende Antwort! =) Den Weg über das Array geh ich, weil es für mich so einfacher ist, da die Werte nicht die einzigen sind, die gelesen werden. Es werden viele verschiedene Werte in ein Array eingelesen und dann bei Bedarf verarbeitet und nur bei einem bestimmten Funktionsaufruf wird wirklich ein Integer draus.

grenzgaenger 1. Sep 2008 20:23

Re: [erledigt] Little-Endian-DWord zu Integer und zurück
 
hier mal eine kleine funktion...

Delphi-Quellcode:
function BigEndian2LittleEndian(aInt: integer): integer;
asm
  xchg ah, al;
  rol eax, 16;
  xchg ah, al;
end;

aber wie du das wieder zurück bekommst :gruebel: :gruebel:

Laufi 1. Sep 2008 21:45

Re: [erledigt] Little-Endian-DWord zu Integer und zurück
 
Hallo!

Zitat:

Zitat von grenzgaenger
aber wie du das wieder zurück bekommst :gruebel: :gruebel:

Indem man es nochmals aufruft du scherz Kecks? :-D

Liebe Grüsse
Laufi


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz