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

Mar*_*ada 3 delphi string 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;
Run Code Online (Sandbox Code Playgroud)

如果我一步一步地运行这个程序,我可以看到arr[0] = 'abbb',在rutine结束时,两个值,arr[0]arr[1]等于baaa.我想它与类型转换有关.

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

Rem*_*eau 5

您的代码有两个问题:

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

  2. 更重要的是,当你输入一个AnsiStringa时PAnsiChar,AnsiString如果AnsiString它不是空的,它会返回一个指向内部数据的指针.您正在型铸造UnicodeStringAnsiString并抓住一个指针到它,所以编译器必须使用编译器生成的局部变量的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;
    
    Run Code Online (Sandbox Code Playgroud)

根据如何记忆compiler_temp得到由在运行时的RTL内存管理器进行管理,这当然是可能的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;
Run Code Online (Sandbox Code Playgroud)