On Sat, 27 Aug 2016 06:03:01 -0400, P E Schoen wrote:
>
> But I would still like to learn more about strings and PChar.
Let's start with the simplest one: ShortString. ShortString storage has a
fixed 256 bytes length. This is why ShortString can't hold more than 255
characters. The first byte is the length of the string. The remaining bytes
are the string characters. The data for "ABC" would be like below (in
hexadecimal) where xx is an undefined byte.
03,41,42,43,xx,xx,...
i.e.
ShortStringStorage = record
StringLength : Byte;
StringData : Array [1..255] of Char;
end;
A pointer to a ShortString (e.g. @MyShortString) would point to the first
byte of its storage - to the string length. MyShortString[0] would also
point to the string length - as Char type. And you can modify the string
length by altering the first byte. SizeOf(MyShortString) will always resolve
to 256 if MyShortString was declared as just ShortString. If it was declared
as ShortString[100], SizeOf(MyShortString) would resolve to 101.
Length(MyShortString) will resolve to the string length.
PChar...
PChar type is just a pointer to a Char type. It doesn't hold any actual
characters. It's equivalent to: ^Char. When used as a string pointer, the
data it points to is expected to be a null-terminated string - to the first
character of the string. SizeOf(MyPChar) would resolve to 4 because it's a
pointer. Length() is not applicable for PChar type. The data for "ABC" would
be like below.
41,42,43,00
String...
String type is a combination between ShortString and PChar (null terminated
string). The String storage layout is like ShortString except that the
string length is 16-bit instead of 8-bit. The data for "ABC" would be like
below.
03,00,41,42,43,00
i.e.
(*
StringStorage = record
StringLength : Word;
StringData : Array [1..n] of Char;
end;
Where n is variable. i.e. variable field size
*)
The type itself works similar to PChar (i.e. a pointer), but it points to
the first character of the string instead to the string length. i.e. to the
third byte. SizeOf(MyString) would also resolve to 4 just like PChar.
Length(MyString) would resolve to the string length. You can't use
MyString[0] to access the string length. It's not allowed because the string
length is 16-bit. You'll have to use Length() instead.
Typecasting to PChar...
String can be safely typecasted to PChar, but not a pointer to ShortString
(PShortString). This is because ShortString is not a null terminated string.
If you need to typecast PShortString to PChar, you'll need to have a null
character following the string data (not the string storage). But be sure
the string length plus the null character doesn't exceed 255 characters.
e.g.
procedure Example;
var MyShortString : ShortString;
var MyString : String;
var MyPChar : PChar;
begin
MyShortString := 'ABC';
if Length(MyShortString) < 255 then
begin
(* Append null character without changing string length *)
MyShortString[Length(MyShortString)+1] := #0;
MyPChar := @MyShortString[1];
end
else
begin
MyString := MyShortString;
MyPChar := PChar(MyString);
end;
Application.MessageBox(MyPChar, 'Dialog', MB_OK);
end;