Reputation: 14873
I often read that the compiler does some kind of magic when casting to PChar
.
The main purpose of PChar
is to call foreign code in libraries that expect a zero terminated array of characters (C style "string").
PChar
is a type that is an alias to PWideChar
on Unicode Delphi and an alias to PAnsiChar
on non-unicode Delphi.
Delphi strings (string
= AnsiString
/ UnicodeString
, I'm not talking about WideString
here, let alone ShortString
...) on the other hand have a hidden length instead of a termination char. They are also reference counted and use copy on write.
Are Delphi strings automatically allocated and kept to be one char longer with an implicit #0 char in order to make casting to a PChar
(PAnsiChar / PWideChar) easier or does the compiler check and adjust the string when it encounters a conversion to PChar
?
Upvotes: 1
Views: 2509
Reputation: 27493
A string variable internally is a pointer into a structure containing prefix, characters and null terminator. Though the structure starts from the prefix (containing string length, ref count, char size and codepage) the pointer points to the first character, so casting to PChar is straightforward.
The magic behind of string -> PChar casting is that always PChar(S) <> nil
, even if string is empty (S = ''
and Pointer(S) = nil
). Instead of returning a string variable pointer 'as is', like Pointer(S)
do, PChar(S)
calls a function that checks whether Pointer(S)
is nil and if Pointer(S) = nil
returns a pointer to a dummy empty string instead of nil
(i.e. a pointer to the null terminator of the dummy empty string).
Upvotes: 3
Reputation: 612794
The process is as follows:
s
has length greater than zero, then PChar(s)
returns a pointer to the first element of the string content. Because the string
is managed to have a hidden null-terminator nothing more needs to be done.s
has length zero, then PChar(s)
returns a pointer to a block of memory containing a null-terminator.As an implementation detail, the null-terminator that is returned from PChar(nil)
is a global constant allocated in the read-only section of the compiled module.
Are Delphi strings automatically allocated and kept to be one char longer with an implicit #0 char in order to make casting to a PChar (PAnsiChar / PWideChar) easier?
Yes.
The magic, if you can call it that, is that:
PChar()
on empty strings returns a pointer to a null-terminator.Upvotes: 11