Ces*_*ero 5 delphi string casting
我有方法(Delphi 2009):
procedure TAnsiStringType.SetData(const Value: TBuffer; IsNull: boolean = False);
begin
if not IsNull then
FValue:= PAnsiString(Value)^;
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
这是基类上的抽象方法,其中"Value:Pointer"需要相应数据的指针,如下所示:
String = PString
AnsiString = PAnsiString
Integer = PInteger
Boolean = PBoolean
Run Code Online (Sandbox Code Playgroud)
所以我尝试传递这样的值:
var
S: AnsiString;
begin
S:= 'New AnsiString Buffer';
SetBuffer(PAnsiString(S));
end;
Run Code Online (Sandbox Code Playgroud)
但是从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;
Run Code Online (Sandbox Code Playgroud)
结果是:
P1: 5006500
P2: 1242488
P3: 1242488
P4: 5006500
P5: 67
Run Code Online (Sandbox Code Playgroud)
哪里:
- 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?
Run Code Online (Sandbox Code Playgroud)
P1和P4是什么意思?
Rob*_*edy 15
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 +---------+ +-----------+ +-----------+ | ... | +-----------+
当我推理指针时,我就像这样绘制图表.如果你不在桌子旁边放一些纸,那你就是在伤害自己.
很好的谜题,但我有解决方案:
我在代码中添加了注释:
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;
Run Code Online (Sandbox Code Playgroud)