Bei PChars kannst du nicht einfach den Zuweisungsoperator (":=") benutzen. Dieser würde nämlich die Zeiger-Adresse auf die Adresse setzen, an der der Compiler den String abgelegt hat.
Dein Code muss also
Delphi-Quelltext
1:
| StrCopy(PChar(Puffer), ''Testtext'); |
lauten.
Um noch einmal auf die Typenkonvertierung zurückzukommen.
Puffer -> $1000
An Speicheradresse $1000 steht: $00 01 02 03 04 05
Mit PChar(Puffer^) machst du nun folgendes:
Delphi-Quelltext
1: 2:
| var P: PChar; P := $00 01 02 03; |
Damit zeigt der neugewonnene Zeiger P nicht auf den reservierten Speicherplatz, sondern wild in den Arbeitsspeicher.
Bei
PChar(Puffer^) := 'Testtext'; überschreibst du die ersten 4 Bytes des Speichers, auf den Puffer zeigt. Dadurch wird aus den oben genannen
$00 01 02 03 die Adresse an der der Compiler 'Testtext' abgelegt hat. Es ist dann natürlich kar, dass du mit
ShowMessage(PChar(Puffer^)) die Adresse von 'Testtext' übergibst. Damit brauchst du gar nicht 255 Bytes reservieren, wenn du sowieso nur 4 davon nutzt.
Das 1. Beispiel kannst du auch so lösen:
Delphi-Quelltext
1: 2: 3: 4: 5:
| var Puffer: PChar; begin Puffer := 'Testtext'; ShowMessage(Puffer); end; |
Bei deinem 2. Beispiel machst du bei der Ausgabe den selben Fehler (vom Schreibfehler
PPuffer mal abgesene).
Die Funktion GetLogicalDriveStrings() schreibt die Daten in den ihr übergebenen PChar, wobei hier zu beachten ist, dass die einzelnen Teilstring mit einem #0-Zeichen von einander getrennt sind. Nach dem letzen Teilstring kommt ein #0#0, dass den gesamten String abschließt.
Wenn du nun PChar(Puffer) an ShowMessage übergibst, gibt diese nur den ersten Laufwerksbuchstaben aus, da das erste #0 als Stringende betrachtet wird. Das noch weitere Laufwerksbuchstaben folgen, kann ShowMessage nicht wissen. Dies muss der Programmierer erledigen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| var P: PChar; S: string; begin P := StrAlloc(255 + 1); try GetLogicalDriveStrings(255, P); while P^ <> #0 do begin SetString(S, P, StrLen(P)); P := StrEnd(P) + 1; ShowMessage(S); end; finally StrDispose(P); end; end; |