Yes :-)
Use shortstrings or pChars
{$WARNINGS ON}
function Test: String;
var
p: pChar;
d: double;
begin
Result := p + FloatToStr(d);
end;
//This code will give a warning.
Seriously
No, the normal Delphi strings and shortstrings are automatically initialized to '' (empty string). Shortstrings live on the stack and don't need cleanup. Other strings are so called 'managed' types and automatically deleted when they are no longer used using reference counting.
PChars, the good news
pChars are just pointers. Delphi does not manage them.
However Delphi does automatically convert them to strings and visa versa.
pChars the bad news
If you convert a pChar to a string Delphi copies the contents of the pChar into the string and you are still responsible for destroying the pChar.
Also note that this copying takes time and if you do it a lot will slow your code down.
If you convert a string to a pChar Delphi will give you a pointer to the address the string lives in. And !! Delphi will stop managing the string. You can still assign values to the string, but it will no longer automatically grow.
From: http://www.marcocantu.com/epascal/English/ch07str.htm
The following code will not work as expected:
procedure TForm1.Button2Click(Sender: TObject);
var
S1: String;
begin
SetLength (S1, 100);
GetWindowText (Handle, PChar (S1), Length (S1));
S1 := S1 + ' is the title'; // this won't work
Button1.Caption := S1;
end;
This program compiles, but when you run it, you are in for a surprise: The Caption of the button will have the original text of the window title, without the text of the constant string you have added to it. The problem is that when Windows writes to the string (within the GetWindowText
API call), it doesn't set the length of the long Pascal string properly. Delphi still can use this string for output and can figure out when it ends by looking for the null terminator, but if you append further characters after the null terminator, they will be skipped altogether.
How can we fix this problem? The solution is to tell the system to convert the string returned by the GetWindowText
API call back to a Pascal string. However, if you write the following code:
S1 := String (S1);
the system will ignore it, because converting a data type back into itself is a useless operation. To obtain the proper long Pascal string, you need to recast the string to a PChar and let Delphi convert it back again properly to a string:
S1 := String (PChar (S1));
Actually, you can skip the string conversion, because PChar-to-string conversions are automatic in Delphi. Here is the final code:
procedure TForm1.Button3Click(Sender: TObject);
var
S1: String;
begin
SetLength (S1, 100);
GetWindowText (Handle, PChar (S1), Length (S1));
S1 := String (PChar (S1));
S1 := S1 + ' is the title';
Button3.Caption := S1;
end;
An alternative is to reset the length of the Delphi string, using the length of the PChar string, by writing:
SetLength (S1, StrLen (PChar (S1)));