如何将字符串传递给PAnsiChar数组?

时间:2013-02-10 03:34:31

标签: string delphi unicode casting delphi-xe2

当我尝试将Lines TMemo控件的PChar字符串传递给procedure Test; var i: smallint; arr: array of PAnsiChar; strarr: array[0..1] of string; begin SetLength(arr, 2); strarr[0] := 'abbb'; strarr[1] := 'baaa'; for i := 0 to Length(strarr) do arr[i] := PAnsiChar(AnsiString(strarr[i])); end; 数组时,会发生奇怪的事情。在例程结束时,数组中的最后一个字符串是重复的。我能够在这个简单的代码中复制它:

arr[0] = 'abbb'

如果我一步一步地运行此程序,我可以看到arr[0]但是,在rutine的末尾,两个值arr[1]baaa等于{{1}} 。我想这与类型转换有关。

任何人都可以看到有什么问题吗?

1 个答案:

答案 0 :(得分:5)

您的代码存在两个问题:

  1. 您的循环超出了数组的上限。它需要使用for i := 0 to Length(strarr)-1 dofor i := 0 to High(strarr) do代替。

  2. 更重要的是,当您向AnsiString输入PAnsiChar时,如果AnsiString,它会返回指向AnsiString内部数据的指针不是空的。您正在向UnicodeString输入AnsiString并抓取指向它的指针,因此编译器必须使用编译器生成的AnsiString数据的局部变量。换句话说,您的代码实际上与以下内容完全相同:

    procedure Test;
    var
      i: smallint;
      arr: array of PAnsiChar;
      strarr: array[0..1] of string;
      compiler_temp: AnsiString;
    begin
      SetLength(arr, 2);
      strarr[0] := 'abbb';
      strarr[1] := 'baaa';
      for i := 0 to Length(strarr) do
      begin
        compiler_temp := AnsiString(strarr[i]);
        arr[i] := PAnsiChar(compiler_temp);
      end;
    end;
    
  3. 取决于RTL内存管理器在运行时如何管理compiler_temp的内存,arr[0]arr[1]最终可能指向相同的物理内容这种情况下的内存块。

    如果您想要一组PAnsiChar值,那么您需要从Ansi数据数组开始,指向它们:

    procedure Test;
    var
      i: Integer;
      arr: array of PAnsiChar;
      strarr: array[0..1] of AnsiString;
    begin
      SetLength(arr, 2);
      strarr[0] := 'abbb';
      strarr[1] := 'baaa';
      for i := 0 to Length(strarr)-1 do
        arr[i] := PAnsiChar(strarr[i]);
    end;