Да: -)
Используйте короткие шорты или pChars
{$WARNINGS ON}
function Test: String;
var
p: pChar;
d: double;
begin
Result := p + FloatToStr(d);
end;
//This code will give a warning.
Серьезно
Нет, нормальный Delphiстроки и короткие строки автоматически инициализируются как '' (пустая строка).Короткие струны живут в стеке и не нуждаются в очистке.Другие строки являются так называемыми «управляемыми» типами и автоматически удаляются, когда они больше не используются с использованием подсчета ссылок.
PChars, хорошие новости
pChars - это просто указатели.Delphi не управляет ими.
Однако Delphi делает автоматически конвертирует их в строки и наоборот.
pChars плохие новости
Если вы преобразуете pChar в строку Delphi копирует содержимое pChar в строку, и вы по-прежнему несете ответственность за уничтожение pChar.
Также обратите внимание, что это копирование занимает время, и если вы это делаетеэто сильно замедлит ваш код.
Если вы преобразуете строку в pChar Delphi даст вам указатель на адрес, в котором находится строка. И !!Delphi перестанет управлять строкой.Вы все еще можете присвоить значения строке, но она больше не будет автоматически расти.
From: http://www.marcocantu.com/epascal/English/ch07str.htm
Следующий код не будет работать должным образом:
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;
Эта программа компилируется, но когда вы ее запустите, вас ждет сюрприз: заголовок кнопки будет иметь исходный текст заголовка окна без текста константной строки, которую вы добавили к нему.Проблема в том, что когда Windows записывает в строку (в рамках вызова API GetWindowText
), она не устанавливает длину длинной строки Pascal должным образом.Delphi все еще может использовать эту строку для вывода и может выяснить, когда она заканчивается, ища нулевой терминатор, но если вы добавите дополнительные символы после нулевого терминатора, они будут вообще пропущены.
Как мы можем это исправитьпроблема?Решение состоит в том, чтобы сказать системе преобразовать строку, возвращаемую вызовом API GetWindowText
, обратно в строку Паскаля.Однако, если вы напишите следующий код:
S1 := String (S1);
, система проигнорирует его, потому что преобразование типа данных обратно в себя - бесполезная операция.Чтобы получить правильную длинную строку Паскаля, вам нужно переписать строку в PChar и позволить Delphi правильно преобразовать ее обратно в строку:
S1 := String (PChar (S1));
На самом деле, вы можете пропустить преобразование строки, потому что PChar-преобразования в строку в Delphi выполняются автоматически.Вот окончательный код:
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;
Альтернативой является сброс длины строки Delphi, используя длину строки PChar, путем записи:
SetLength (S1, StrLen (PChar (S1)));