AnsiString?PChar?赋值?转换?

2008-02-23 07:18:14来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

记得原来给aiirii(ari)胡诌了一通PChar和string,一直感觉心里有愧,现在好好说一说这个知识点。

AnsiString?PChar?赋值?转换?

AnsiString,Delphi开发人员指南这么解释的,AnsiString就是指向堆中字符串结构的指针,显示了AnsiString的分配情况。
帮助上这么解释:长字符串保存有成员数量,PChar没有,长字符串(相对于ShortString类型来说,这里就是AnsiString)是Null结尾的,并且包含了引用记数,PChar就是一个简单的Null结尾的字符串。AnsiString之间的赋值是赋值数据,而PChar赋值是改变指针的指向。

同样存储LIKE,两种类型差异:

string简图:
--------------------------------------------------------
| 引用计数位 | 长度位 | L | I | K | E | #0 |
--------------------------------------------------------

PChar简图:
-------------------------
| L | I | K | E | #0 |
-------------------------

而string的指针通常指向数据位第一个,访问前面的引用计数和长度位的时候word ptr [eax-$04], dword ptr [eax-$08],这一类的代码。

它们之间的转换,Delphi开发人员指南里面是这么写的:不需要用StrPas和StrPCopy去来回转换string和PChar类型。我们在前面讲过,可以把AnsiString强制转化成PChar。在想把PChar转换成AnsiString时,可以直接赋值:StringVar := PCharVar;

StrPas的原型是什么?我悄悄地告诉你啊,不要告诉别人哦!:〉
function StrPas(const Str: PChar): string;
begin
Result := Str;
end;
哈哈,搞笑吧。Borland弄了这么一个东西…… -_-bb
其实是为了兼容而设立的。

StrPCopy相对来讲就比较复杂了,是把string强制转化成PChar之后按照string的长度进行PChar之间复制。

function StrPCopy(Dest: PChar; const Source: string): PChar;
begin
Result := StrLCopy(Dest, PChar(Source), Length(Source));
end;

而StrLCopy类似于C语言里面的strcpy这种用来复制内容的函数,所以尽量用StrLCopy来给PChar赋值,
因为会保护现场,用赋值号,就改变了指针的指向了。

有关Delphi开发人员指南里面的介绍,我写了这么一些代码来验证一下:
var
P: PChar;
S: string;
begin
S := '1234567ABCDE';
P := PChar(S);
S := P;
ShowMessage(S);
ShowMessage(P);
ShowMessage(IntToStr(SizeOf(S)));
end;

当执行到S := '1234567ABCDE';时,汇编代码如下:

第一句:S := '1234567ABCDE';
0045B130 8D45FC lea eax,[ebp-$04]
0045B133 BAB0B14500 mov edx,$0045b1b0
0045B140 E8E791FAFF call @LStrLAsg

LStrLAsg就是字符串赋值地内建函数。正验证了帮助里面的那句string之间是数据Copy。

第二句:P := PChar(S);
0045B13D 8B45FC mov eax,[ebp-$04]
0045B140 E8FF95FAFF call @LStrToPChar
0045B145 8BD8 mov ebx,eax

进入这一句了,LStrToPChar是不是很容易理解呢,string转化为PChar。然后简单的赋地址,指针改变指向。

好了该由PChar转换到string了,这个是一个重点。

第三句:S := P;
0045B147 8D45FC lea eax,[ebp-$04]
0045B14A 8BD3 mov edx,ebx
0045B14C E83393FAFF call @LStrFromPChar

LStrFromPChar是由PChar转换string的一个内建函数。

进入LStrFromPChar的代码
@LStrFromPChar
00404484 31C9 xor ecx,ecx
00404486 85D2 test edx,edx
00404488 7421 jz $21
0040448A 52 push edx
0040448B 3A0A cmp cl,[edx]
0040448D 7417 jz $17
0040448F 3A4A01 cmp cl,[edx $01]
00404492 7411 jz $11
00404494 3A4A02 cmp cl,[edx $02]
00404497 740B jz $0b
00404499 3A4A03 cmp cl,[edx $03]
0040449C 7405 jz $05
0040449E 83C204 add edx,$04
004044A1 EBE8 jmp -$18 //循环得到字符串长度。
004044A3 42 inc edx
004044A4 42 inc edx
004044A5 42 inc edx
004044A6 89D1 mov ecx,edx
004044A8 5A pop edx
004044A9 29D1 sub ecx,edx //到这里得到了PChar的长度。
004044AB E9D4FEFFFF jmp @LStrFromPCharLen
004044B0 C3 ret

然后处理成string的长度的转化:

@LStrFromPCharLen
00404384 53 push ebx
00404385 56 push esi
00404386 57 push edi
00404387 89C3 mov ebx,eax
00404389 89D6 mov esi,edx
0040438B 89CF mov edi,ecx
0040438D 89F8 mov eax,edi
0040438F E8C4FFFFFF call @NewAnsiString

这里调用了NewAnsiString来生成一个新的标准字符串。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Delphi控制并行端口位操作

下一篇:对《QQ列表精灵》源代码分析和仿制