Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Speicherinhalt eines Records identisch wie mit jenem in C? (https://www.delphipraxis.net/170989-speicherinhalt-eines-records-identisch-wie-mit-jenem-c.html)

hedie 14. Okt 2012 15:08

Speicherinhalt eines Records identisch wie mit jenem in C?
 
Guten Nachmittag liebe Community...

Draussen ist es grau bei uns in der Schweiz, und deshalb ist es mal wieder Zeit für ein bisschen Programmieren mit Delphi :)

Da kommt auch schon die erste Frage auf.

Wie sieht eigentlich die Datenstruktur im Speicher für ein Record aus?
Bei C ist es ja so, dass wenn man beispielsweise folgende Struktur (struct) hat:

Code:
TColixHeader = record
    DestinationAddr: Word;
    SourceAddr: Word;
    PaketType: Byte;
    PaketCounter:Byte;
    PaketStatusBits:Byte;
  end;
Es im Speicher wie folgt aussieht:

[2bytes][2bytes][1bytes][1byte][1byte]

Und dies auch nacheinander entsprechend dem Struct halt eben.
Ich gehe mal davon aus, das dies bei Delphi ebenso ist.

Der Hintergrund dazu:

Ich möchte selbst definierte Paketstrukturen innerhalb eines UDP Paketes im Netz versenden.
Empfangen wird dies unter anderem auch von einem C-Programm.

Und dort ist es halt besonders vorteilhaft, wenn man die empfangenen Bytes gleich in ein
Struct laden kann und dann über dieses auf die entsprechenden Daten zugreifen kann.

Dies setzt jedoch eine immer gleichbleibende Datenstruktur (auf Byteebene) voraus.

(Deshalb die frage ob die Struktur im Speicher identisch ist)

Ich würde dann eben etwas im folgenden Stil machen:

Code:
// In Delphi
...sendeUDP(MeineRecordDaten)...


//im C-Programm
...meinStruct = empfangeUDP()...
In Delphi verwende ich die Jedi Komponenten (tIdUDPClient) zum senden.
Diese erwartet jedoch einen String.

Weiss jemand, 1) wie man an die "rohdaten" (bytes) eines Records kommt
und wie man diese dann mit dem tIdUDPClient senden kann?

Genügt die Funktion bytesToString(MeineRecordBytes) ?

Danke schonmal
Grüsse
Claudio

Zacherl 14. Okt 2012 15:26

AW: Speicherinhalt eines Records identisch wie mit jenem in C?
 
Du kannst dazu .IOHandler.ReadBytes verwenden. Um sicher zu gehen, dass deine Records nicht aligned werden, solltest du sie außerdem als packed record deklarieren :)

hedie 14. Okt 2012 15:42

AW: Speicherinhalt eines Records identisch wie mit jenem in C?
 
Besten Dank für deine Antwort...

Ich habe zum testen mal folgenden Code geschrieben:

Delphi-Quellcode:
.....
  TColixHeader = packed record
    DestinationAddr: Word;
    SourceAddr: Word;
    PaketType: Byte;
    PaketCounter:Byte;
    PaketStatusBits:Byte;
  end;
.....


procedure TForm1.Button8Click(Sender: TObject);
var
myArray: array of Byte;
myHeader:TColixHeader;
begin

SetLength(myArray,7);

myArray[0] := 0;
myArray[1] := 20;

myArray[2] := 0;
myArray[3] := 50;

myArray[4] := 20;

myArray[5] := 7;

myArray[6] := 5;

move(myArray,myHeader,7);

debugEntry('DestinationAddr: '+inttostr(myHeader.DestinationAddr));
debugEntry('SourceAddr: '+inttostr(myHeader.SourceAddr));

debugEntry('PaketType: '+inttostr(myHeader.PaketType));
debugEntry('PaketCounter: '+inttostr(myHeader.PaketCounter));
debugEntry('PaketState: '+inttostr(myHeader.PaketStatusBits));

end;
Doch leider scheint dies nicht zu klappen...

Dabei kommt immer folgendes heraus:

Code:
2:16:38:42 - DestinationAddr: 59376
3:16:38:42 - SourceAddr: 144
4:16:38:42 - PaketType: 240
5:16:38:42 - PaketCounter: 246
6:16:38:42 - PaketState: 24
Ich dachte zuerst, dass es daran liegt, das ich ein word mittels IntToStr versuche zu konvertieren.
Aber laut der DP ist das der normale weg...

Gibt es eine möglichkeit, in den Speicher an dem das Record liegt hineinzuschauen?

Danke schonmal

nuclearping 14. Okt 2012 16:03

AW: Speicherinhalt eines Records identisch wie mit jenem in C?
 
Delphi-Quellcode:
move(myArray[0], myHeader, 7);

hedie 14. Okt 2012 16:17

AW: Speicherinhalt eines Records identisch wie mit jenem in C?
 
vielen herzlichen Dank!

Hat alles wunderbar geklappt.

Zacherl 14. Okt 2012 19:53

AW: Speicherinhalt eines Records identisch wie mit jenem in C?
 
Zur Erklärung: Dynamische Arrays sind in Delphi keine direkten Zeiger auf einen zusammenhängenden Speicherbereich. @Array[0] stellt den wirklichen Begin des Speicherbereichs da, während @Array nur einen Zeiger auf den Zeiger von Speicherbereich ist.

Statt @Array[0] wäre folglich auch @Pointer(Array)^ möglich, wobei das ziemlich unüblich ist.


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