Strings versenden

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Strings versenden

Beitrag von mse »

Wenn ich jetzt folgenden Code habe:

var s:string;

s:='Hallo';
WriteString(s);


Bei einem ShortString würden jetzt "vermutlich" 5 Bytes gesendet werden.
Das Längenbyte und die ersten 4 Buchstaben "Hall"
Das letzte "o" würde also fehlen,
Weil im ersten Byte befindet sich ja die Längenangabe und dann folgen die Asciizeichen.
demnach müste ich schreiben:
WriteFile(fHandle,s[1],length(s),written,@Foverlapped);
Korrekt.
Aber was, wenn es kein ShortString ist ?

Bei einem Nullterminierten String muss ich s[0] verwenden.
Nein, das erste Zeichen ist immer Index 1.
Stellt sich mir grad die Frage woher die Funktion length eigentlich weis, wie die Länge des Strings ermittelt wird.
Ein langer String ist ein Pointer auf das erste Zeichen (= Adresse von s[1]) des strings. Davorgestellt ist eine Speicherblock mit diesem Aufbau (aus rtl/inc/astrings.inc):

Code: Alles auswählen

 
{
  This file contains the implementation of the AnsiString type,
  and all things that are needed for it.
  AnsiString is defined as a 'silent' pchar :
  a pchar that points to :
 
  @-16 : Code page indicator.
  @-12 : Character size (2 bytes)
  @-8  : SizeInt for reference count;
  @-4  : SizeInt for size;
  @    : String + Terminating #0;
  Pchar(Ansistring) is a valid typecast.
  So AS[i] is converted to the address @AS+i-1.
 
  Constants should be assigned a reference count of -1
  Meaning that they can't be disposed of.
}
 
Type
  PAnsiRec = ^TAnsiRec;
  TAnsiRec = Record
    CodePage    : TSystemCodePage;
    ElementSize : Word;
{$ifdef CPU64}	
    { align fields  }
	Dummy       : DWord;
{$endif CPU64}
    Ref         : SizeInt;
    Len         : SizeInt;
  end;
 
Die Offsets sind für 32 Bit, auf 64Bit Systemen ist SizeInt 8Byte breit. Ein leerer string ('') ist ein NIL-Pointer.
Also erscheint mir meine SendeRoutine für Strings relativ unkontrolliert
und daher meine Frage: wie mache ich das am Sinnvollsten.

Code: Alles auswählen

 
Procedure WriteString(s:string);
var written:cardinal; 
bein
  WriteFile(fHandle,s[1],length(s),written,@Foverlapped);
end;
 
sollte immer funktionieren.

Mathias
Beiträge: 6943
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Strings versenden

Beitrag von Mathias »

Vor dem schreiben aber pruefen, das der String groesser 0 ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Strings versenden

Beitrag von mse »

Ich glaube nicht, dass das notwendig ist. Der Datenpointer ist dann zwar ungültig, da nNumberOfBytesToWrite 0 ist, schadet es nicht.

siro
Beiträge: 761
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Strings versenden

Beitrag von siro »

Guten Morgen,
so früh schon so gute Info:
Supi, ich Danke Dir "mse"

Die entscheidenden Bytes liegen also "davor" im Speicher und s[1] ist immer das erste Zeichen.
So macht das jetzt auch für mich einen Sinn. @-xx das (MINUS) löst mein Rätsel.
Das ist natürlich sehr gut gelöst und damit auch SEHR kompatibel.

Ihr seid Spitze, geniesst das Wochenende.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Mathias
Beiträge: 6943
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Strings versenden

Beitrag von Mathias »

mse hat geschrieben:Ich glaube nicht, dass das notwendig ist. Der Datenpointer ist dann zwar ungültig, da nNumberOfBytesToWrite 0 ist, schadet es nicht.
Wen man die Bereichsprüfung aktiviert, dann kommt es zu einem Fehler.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten