将AnsiString转换为Unicode字符串

jro*_*nhi 5 delphi unicode encoding delphi-2010

我正在将D2006程序转换为D2010.我的数据库中每个字符串都有一个存储在单个字节中的值,我需要将其加载到具有LoadFromStream的控件中,因此我的计划是将字符串写入流并将其与LoadFromStream一起使用.但它没有用.在研究这个问题时,我看到一个问题告诉我,我真的不明白从AnsiString到Unicode字符串的转换是如何工作的.这是一段独立的代码,说明了我感到困惑的问题:

procedure TForm1.Button1Click(Sender: TObject); {$O-}
var
  sBuffer: String;
  oStringStream: TStringStream;
  sAnsiString: AnsiString;
  sUnicodeString: String;
  iSize1,
  iSize2: Word;
begin
  sAnsiString := '12345';
  oStringStream := TStringStream.Create(sBuffer);
  sUnicodeString := sAnsiString;
  iSize1 := StringElementSize(sAnsiString);
  iSize2 := StringElementSize(sUnicodeString);
  oStringStream.WriteString(sUnicodeString);
end;
Run Code Online (Sandbox Code Playgroud)

如果你在最后一行中断,并检查oStringStream的Bytes属性,你会看到它看起来像这样:

Bytes (49 {$31}, 50 {$32}, 51 {$33}, 52 {$34}, 53 {$35}
Run Code Online (Sandbox Code Playgroud)

我期待它可能看起来像

(49 {$31}, 00 {$00}, 50 {$32}, 00 {$00}, 51 {$33}, 00 {$00}, 
 52 {$34}, 00 {$00}, 53 {$35}, 00 {$00} ...
Run Code Online (Sandbox Code Playgroud)

显然我的期望是错误的.但是,如何将AnsiString转换为unicode?

我没有从LoadFromStream中获得正确的结果,因为它一次从流中读取两个字节,但它接收的数据不是那样排列的.我应该做些什么来为LoadFromStream提供基于unicode字符串的良好数据流?

谢谢您的帮助.

klu*_*udg 5

oStringStream.WriteString的参数是什么类型的?如果它是AnsiString,你有一个从Unicode到Ansi的隐式转换,这解释了你的例子.


更新:现在真正的问题是TStringStream如何在内部存储数据.在以下代码示例中(Delphi 2009)

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S);  // 1 byte per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;
Run Code Online (Sandbox Code Playgroud)

TStringStream在内部使用默认的系统ANSI编码(每个字符1个字节).构造函数和WriteString过程将字符串参数从unicode转换为ANSI.

要覆盖此行为,您必须在构造函数中明确声明编码:

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  SS: TStringStream;

begin
  S:= 'asdfg';
  SS:= TStringStream.Create(S, TEncoding.Unicode);  // 2 bytes per char
  SS.WriteString('321');
  Label1.Caption:= SS.DataString;
  SS.Free;
end;
Run Code Online (Sandbox Code Playgroud)