AnsiString?PChar?赋值?转换?(2)
2008-02-23 07:18:14来源:互联网 阅读 ()
我们跳过来顺道看看string到底怎么生成的。string生成尽管是自动的,
其实和手工声称PChar差不多,不同的是比PChar多的长度位和引用计数的初始化。
@NewAnsiString
00404358 85C0 test eax,eax
0040435A 7E24 jle $24
0040435C 50 push eax
0040435D 83C00A add eax,$0a
00404360 83E0FE and eax,-$02
00404363 50 push eax
00404364 E8B3E3FFFF call @GetMem //得到字符串长度后申请内存。
00404369 5A pop edx
0040436A 66C74402FE0000 mov word ptr [edx eax-$02],$0000
00404371 83C008 add eax,$08
00404374 5A pop edx
00404375 8950FC mov [eax-$04],edx //这里应该就长度位
00404378 C740F801000000 mov [eax-$08],$00000001 //这里是引用记数位
0040437F C3 ret
00404380 31C0 xor eax,eax
00404382 C3 ret
00404383 90 nop
继续LStrFromPCharLen下面的代码。
00404394 89F9 mov ecx,edi
00404396 89C7 mov edi,eax
00404398 85F6 test esi,esi
0040439A 7409 jz $09
0040439C 89C2 mov edx,eax
0040439E 89F0 mov eax,esi
004043A0 E873E5FFFF call Move //然后把这个新的字符串的数据移到需要的字符串。
004043A5 89D8 mov eax,ebx
004043A7 E8E8FEFFFF call @LStrClr //清理NewAnsiString生成的临时字符串
004043AC 893B mov [ebx],edi
004043AE 5F pop edi
004043AF 5E pop esi
004043B0 5B pop ebx
004043B1 C3 ret
ShowMessage直接输入string就是直接调用。
ShowMessage(S);
0045B159 8B45FC mov eax,[ebp-$04]
0045B15C E8638EFDFF call ShowMessage
而输入PChar,嗬嗬,又调用了上面说到的LStrFromPChar然后才是调用ShowMessage,
其他的也是如此,如果输入参数没有转换,而是输入了PChar,那编译器会这么处理。
ShowMessage(P);
0045B161 8D45F8 lea eax,[ebp-$08]
0045B164 8BD3 mov edx,ebx
0045B166 E81993FAFF call @LStrFromPChar
0045B16B 8B45F8 mov eax,[ebp-$08]
0045B16E E8518EFDFF call ShowMessage
最后一句:ShowMessage(IntToStr(SizeOf(S)));
如果没有差错的话,就是4,一个指针的长度。
好了,一切都清晰了。
S := S;
使用了LStrLAsg内建函数来赋值。
P := P;
地址赋值。
P := PChar(S);
调用LStrToPChar转换为PChar之后地址赋值。
S := P;
这个最最麻烦,
调用LStrFromPChar来转化。
代码中首先取得PChar的长度,
然后调用LStrFromPCharLen用string的长度赋值,
代码中首先使用NewAnsiString在堆中生成一个临时字符串,
其次调用Move,Copy到目的字符串,
最后清理临时字符串。
好了,我又一次胡诌完毕了。请大家执正!
这是我写的,leeon你看看怎么样,我自己总结的:
关于Delphi 中 String (又叫 LongString、AnsiString) 与传统的 PChar的区别
1. string 是 Delphi 编译器内在支持的(predefined or built-in),是Delphi 的一个基本数据类型,而 PChar 只是一个指向零终止字符串的指针;
2. String 所存字符串是在堆(Heap)分配内存的,String 变量实际上是指向零终止字符串的指针,与此同时它还具有引用计数(reference count)功能,并且自身保存字符串长度,当引用计数为零时,自动释放所占用的空间。
3.将 string 赋值给另一个string,只是一个简单的指针赋值,不产生 copy 动作,只是增加string的引用计数;
4. 将一个 PChar 变量类型赋值给一个 string 变量类型会产生真正的 Copy 动作,即将 PChar 所指向的字符串整个copy到为string分配的内存中;
5. 将 string 赋值给一个 PChar 变量类型,只是简单地将string的指针值赋值给PChar 变量类型,而string 的引用计数并不因此操作而发生变化,因为这种情况 PChar 会对 string 产生依赖,当string 的引用计数为零自动释放内存空间后,PChar很可能指向一个无效的内存地址,在你的程序你必须小心对付这种情况。
6. 对 PChar 的操作速度要远远高于对 string 操作的速度,但 PChar 是一种落后的管理字符串的方式,而 string 则以高效的管理而胜出,PChar 它的存在只是为了兼容早期的类型和操作系统(调用 Windows API时会经常用到),建议平常使用 string。
你的那个demo程序我认为设计得非常糟糕,基本上说不清问题:
我设计的Demo程序:
procedure TForm1.Button1Click(Sender: TObject);
var
P: PChar;
S1, S2: string;
begin
S1 := '1234567ABCDE';
S2 := S1;
P := PChar(S1);
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Delphi控制并行端口位操作
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
