当前位置:  开发笔记 > 编程语言 > 正文

将AnsiString强制转换为PAnsiString会发生什么?

如何解决《将AnsiString强制转换为PAnsiString会发生什么?》经验,为你挑选了2个好方法。

我有方法(Delphi 2009):

procedure TAnsiStringType.SetData(const Value: TBuffer; IsNull: boolean = False);
begin
  if not IsNull then
    FValue:= PAnsiString(Value)^;
  inherited;
end;

这是基类上的抽象方法,其中"Value:Pointer"需要相应数据的指针,如下所示:

String = PString
AnsiString = PAnsiString
Integer = PInteger
Boolean = PBoolean

所以我尝试传递这样的值:

var
  S: AnsiString;
begin
  S:= 'New AnsiString Buffer';
  SetBuffer(PAnsiString(S));
end;

但是从AnsiString到PAnsiString的转换不起作用,我可以看出原因,但我想知道转换的结果是什么.所以我写了一个简单的测试:

var
  Buffer: AnsiString;
  P1: Pointer;
  P2: Pointer;
  P3: Pointer;
  P4: Pointer;
begin
  P1:= PAnsiString(Buffer);
  P2:= Addr(Buffer);
  P3:= @Buffer;
  P4:= Pointer(Buffer);
  P5:= PChar(Buffer[1]);

  WriteLn('P1: ' + IntToStr(Integer(P1)));
  WriteLn('P2: ' + IntToStr(Integer(P2)));
  WriteLn('P3: ' + IntToStr(Integer(P3)));
  WriteLn('P4: ' + IntToStr(Integer(P4)));
  WriteLn('P5: ' + IntToStr(Integer(P5)));
end;

结果是:

P1: 5006500
P2: 1242488
P3: 1242488
P4: 5006500
P5: 67

哪里:

- P2 and P3, is the address of Buffer: AnsiString 
- P5 is the Char Ord value of Buffer[1] char, in this case "67 = C"
- How about P1 and P4?

P1和P4是什么意思?



1> Rob Kennedy..:

An AnsiString实现为指针.一个AnsiString变量保存不过是一个地址.地址是字符串中第一个字符的地址,或者nil字符串是否为空.

A PAnsiString是指向AnsiString 变量的指针.它是指向字符串第一个字符的指针.当你说PAnsiString(Buffer),你告诉编译器将指针Buffer视为一个指针AnsiString而不是指向字符数据的指针.地址5006500是字符串的第一个字符的位置C.

您在内存中有一条代表字符串的记录:

                +-----------+
                | $ffffffff | -1 reference count (4 bytes)
                +-----------+
Buffer:         | $00000001 | length (4 bytes)
+---------+     +-----------+
| 5006500 | --> |       'C' | first character (1 byte)
+---------+     +-----------+
                |        #0 | null terminator (1 byte)
                +-----------+

Buffer保存字节的地址C.你输入类型PAnsiString而不是类型AnsiString.你告诉编译器你有这个布局:

                                  +-----------+
                                  |       ... |
                                  +-----------+
Buffer:                           |       ... |
+---------+     +-----------+     +-----------+
| 5006500 | --> | $00000043 | --> |   garbage | first character
+---------+     +-----------+     +-----------+
                                  |       ... |
                                  +-----------+

当我推理指针时,我就像这样绘制图表.如果你不在桌子旁边放一些纸,那你就是在伤害自己.



2> Toon Krijthe..:

很好的谜题,但我有解决方案:

P2和P3是指向缓冲区的指针的地址

P1和P4是缓冲区的地址

P5是缓冲区中的第一个元素

我在代码中添加了注释:

var
  Buffer: AnsiString;
  P1: Pointer;
  P2: Pointer;
  P3: Pointer;
  P4: Pointer;
  P5: Pointer;
begin
  P1:= PAnsiString(Buffer); 
  (* A cast from AnsiString to PAnsiString has no real meaning 
     because both are a pointer to a block of characters ()
  P2:= Addr(Buffer);
  P3:= @Buffer;
  (* Both Addr and @ give the address of a variable. The variable Buffer is 
     a pointer so we get the address of the pointer, not the value of the 
     pointer. *)
  P4:= Pointer(Buffer);
  (* See the remark on P1. Due to the cast both give the same result. *)
  P5:= PChar(Buffer[1]);
  (* This looks like a pointer to the first element. But the cast changes 
     it into the character. *)
  WriteLn('P1: ' + IntToStr(Integer(P1)));
  WriteLn('P2: ' + IntToStr(Integer(P2)));
  WriteLn('P3: ' + IntToStr(Integer(P3)));
  WriteLn('P4: ' + IntToStr(Integer(P4)));
  WriteLn('P5: ' + IntToStr(Integer(P5)));
end;

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有