使用包含WideString的记录指针的New / Dispose

时间:2016-06-10 08:05:47

标签: delphi unicode delphi-7

我有非常旧的代码(来自D3):

TMyRecord  = record
  Index   : Integer;
  Header  : String[70];
  Strings : Array[1..MAX_VALUES] of String[70];
end;

TMyClass = class(TComponent)
  FData  : ^TMyRecord;
  ...
end;

constructor TMyClass.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  New(FData);     
  ...
end;

destructor TMyClass.Destroy;
begin
   Dispose(FData);
   inherited;
end;

问:将String[70]替换为WideString;,将Array[1..MAX_VALUES] of String[70]替换为Array[1..MAX_VALUES] of WideString是否安全? (请解释原因)

我需要这个在Delphi 7中支持Unicode。

1 个答案:

答案 0 :(得分:7)

一般来说,你永远不应该使用Widestring。 它仅用于与COM BSTR兼容。

但是您使用的是2009年之前的版本,因此如果您需要 Unicode,则无法选择。
WideString是动态分配的,当你dispose记录Delphi将添加代码来初始化你的字符串。
你不必自己初始化它们。

就像短弦一样,WideStrings不会被引用计数,但是当你MyWidestring[i]记录时它们会被销毁。
如果你将Widestring分配给另一个Widestring Delphi会复制,这比refcounting效率稍差,但不是一个问题。

每当Widestring超出范围时,它就会被销毁。

注意PWideChar,当WideString被破坏时,这些将悬空。

VCL无法显示WideString
请注意,虽然Delphi 7 确实支持使用Widestring的Unicode,但VCL无法显示您的Widestrings,它只能显示AnsiString。
如果要显示WideStrings使用TNT组件,请参阅此答案以获取更多信息:Handling a Unicode String in Delphi Versions <= 2007

如果要将WideString分配给(Ansi)字符串,您可以使用纯字符串,因为您将丢失所有的unicode。
您可以使用UTF8,但D7也不能显示UTF8。

警告:亚洲语言环境中的索引
另一个警告是String[70]并不一定意味着第i个字符,因为Unicode不能以每个字符2个字节完全表示。
除非您使用亚洲语言,否则这不会影响您。

  

问:用WideString替换String [70]是否安全;

是的,但更容易用String(又名AnsiString)替换{{1}}。因为D7 VCL支持AnsiString但不支持WideString 除此之外,你真的没有问题。

进一步阅读
https://grahamwideman.wikispaces.com/Delphi+String+Types