Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Packed Records und Zeichenketten (https://www.delphipraxis.net/106344-packed-records-und-zeichenketten.html)

Neutral General 9. Jan 2008 14:43


Packed Records und Zeichenketten
 
Hi,

Ich werde/will/tue packed records übers Netzwerk/Internet verschicken. Der String (bzw. Allgemein: die Zeichenkette) soll in einem Record sein. "Normale" Strings kann ich ja nicht nehmen. Strings mit begrenzter Länge gehn leider auch nicht. Geht das irgendwie mit PChar oder einen Array of Char ? Ich steh grad bisschen auf der Leitung.

Gruß
Neutral General

mkinzler 9. Jan 2008 14:46

Re: Packed Records und Zeichenketten
 
Zitat:

Strings mit begrenzter Länge gehn leider auch nicht
Warum nicht?

Neutral General 9. Jan 2008 14:48

Re: Packed Records und Zeichenketten
 
Weil: Eventuell lange Texte > 255 Zeichen :wink:

Dax 9. Jan 2008 14:49

Re: Packed Records und Zeichenketten
 
Wenn du nur einen string hast, kannst du etwas gemeines tun:
Delphi-Quellcode:
type
  PMeanRecord = ^TMeanRecord;
  TMeanRecord = packed record
    Size: Integer;
    // deine Felder
    Text: array[1..MaxInt] of Char; //(eigentlich 1..Size)
  end;

const
  TMeanRecordMinimumSize = 4; //+Größe deiner Felder
Diesen Record darfst du *nur* über GetMem initialisieren. New oder Variablen des Recordtyps sind absolut verboten:
Delphi-Quellcode:
var
  rec: PMeanRecord;

GetMem(rec, TMeanRecordMinimumSize + stringLength);
Wenn du mehrere Strings brauchst... Nun, Pech gehabt. Dann musst du dir Handler dafür schreiben.

Christian Seehase 9. Jan 2008 14:51

Re: Packed Records und Zeichenketten
 
Moin Michael,

Zitat:

Zitat von Neutral General
Der String (bzw. Allgemein: die Zeichenkette) soll in einem Record sein.

Wenn Du HugeStrings verschicken willst, geht das eh' nur speparat, da sie im Record ja nur als Pointer gespeichert werden.

RavenIV 9. Jan 2008 14:53

Re: Packed Records und Zeichenketten
 
Du kannst nehmen:
TextString: String[100];

Zitat:

Zitat von Delphi-Hilfe
Delphi unterstützt kurze String-Typen (Untertypen von ShortString), deren maximale Länge zwischen 0 und 255 Zeichen liegen kann. Diese Typen werden mit einer Zahl in eckigen Klammern dargestellt, die auf das reservierte Wort string folgt. Beispiel:

var MyString: string[100];
Hier wird die Variable MyString mit einer maximalen Länge von 100 Zeichen erstellt.


Neutral General 9. Jan 2008 14:54

Re: Packed Records und Zeichenketten
 
Hi Dax,

Brauche nur einen String :) Und wenn ich das so mache dann brauche ich auch wirklich nur Size(Record ohne String) + Length(String) Bytes? Ich kanns kaum fassen :)
Ok das es mit New bzw Variablen vom Record selbst nicht geht ist mir jetzt auch klar, weeeiil sonst hätte ich Monsterrecords, die ich sicher verschicken will -.-^^

"145 Bytes runtergeladen von 5.32MB von 'Hallo Welt#0#0[...]#0'" :mrgreen:

Gruß
Neutral General

Dax 9. Jan 2008 14:56

Re: Packed Records und Zeichenketten
 
Das dürfte eher in Richtung 2^31+x Bytes gehen, nicht nur 5,32 MB ;)

Neutral General 9. Jan 2008 15:04

Re: Packed Records und Zeichenketten
 
Achja... Kann den String nicht genau MaxInt Bytes groß machen...

Zitat:

[Error] Client.pas(24): Data type too large: exceeds 2 GB
:arrow: (quasi)

Delphi-Quellcode:
x := SizeOf(Record-String);
Text: array[1..MaxInt-x] of Char;

Dax 9. Jan 2008 15:09

Re: Packed Records und Zeichenketten
 
Dann verwende eine sinnvolle Obergrenze wie (1 shl 29), das dürfte sicherlich reichen... Oder du schaltest das Range checking aus und benutzt gleich [0..0].

Reinhard Kern 9. Jan 2008 15:16

Re: Packed Records und Zeichenketten
 
Zitat:

Zitat von Neutral General
Achja... Kann den String nicht genau MaxInt Bytes groß machen...

Zitat:

[Error] Client.pas(24): Data type too large: exceeds 2 GB
:arrow: (quasi)

Delphi-Quellcode:
x := SizeOf(Record-String);
Text: array[1..MaxInt-x] of Char;

Niemand verschickt solche Daten "am Stück". Texte kann man zeilenweise verschicken, Binärdaten in Blöcken von 128 Bytes oder was geeignet ist. Meiner Ansicht nach ist ein String mit 2 GB in jedem Fall ein Fehler im Konzept.

Gruss Reinhard

Dax 9. Jan 2008 15:19

Re: Packed Records und Zeichenketten
 
Eben, deswegen wird der nie 2GB groß ;) Lies mal meinen Beitrag aber böse Tricks mit dem Speichermanager weiter oben.

Muetze1 9. Jan 2008 16:39

Re: Packed Records und Zeichenketten
 
Och, bei der Lösung ist man aber auch wieder eingeschränkt. Warum nicht einfach ein kleines Protokoll definieren? Beispiel:

1. Integer (4 Bytes) Länge der folgenden Zeichenkette
2. Zeichenkette in der Länge wie zuvor angegeben.

Delphi-Quellcode:
procedure SendString(AText: string);
var
  lLen: Integer;
begin
  lLen := length(AText);
  Socket.SendBuf(lLen, sizeof(lLen));
  if lLen > 0 then
    Socket.SendBuffer(AText[1], lLen);
end;
bzw. empfangen:

Delphi-Quellcode:
function ReceiveString: string;
var
  lLen: Integer;
begin
  Socket.ReceiveBuf(lLen, sizeof(lLen));
  if lLen > 0 then
  begin
    SetLength(Result, lLen);
    Socket.ReceiveBuf(result[1], lLen);
  end;
end;

Neutral General 9. Jan 2008 18:27

Re: Packed Records und Zeichenketten
 
@Muetze1: Klar. Aber das funktioniert nicht wenn der String in einem Record ist und man das ganze Record verschickt...

Dax 9. Jan 2008 18:48

Re: Packed Records und Zeichenketten
 
Der Sinn hinter einem solchen Protokoll ist ja auch, eben nicht den gesamten Record zu verschicken, sondern die einzelnen Komponenten.


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