呵呵,pchar是指向以null结尾的char字符串的指针,在调用winapi的时候最好用这种。
解决方案 »
- 改版了?打开网页速度慢很多
- DBgrideh怎样遍历某一列的值
- 高手请赐教 delphi quickreport 分组报表应该怎么实现?
- 关于电信网上营业系统的问题
- 如何让picklist只能从中选而不能输入?
- ----------请问如何把多个TFileStream用TList保存?---------------
- 怎么设计出可以分块安装的软件?如WINDOWS的组件安装一样.
- 还是没调出来,请高手帮忙啊?关于这个access数据库的备份和还原代码?
- 一个很基础的问题————有人讲明白吗?
- 问题没有人答的??
- 请问如何安装delphi的控件!
- 怎么把paradox表中的timestamp类型的字段(包括date,time),分别提出date,time?
则有PChar(s)^ = 'C',(PChar(s)+1)^='S',……(PChar(s)+4)^=#0。
且:PInteger(Integer(Pointer(s))-1*sizeof(DWORD))^=length(s)
和:PInteger(Integer(Pointer(s))-2*sizeof(DWORD))^=refcount(s)可视化一下就是:
[RefCount: DWORD][Length: DWORD]^['C']['S']['D']['N'][#0]
(^处即为s所指内存地址)可以看到string在s之后的内存布局同PChar完全一致,都是ASCIIZ标准的字串,因此任何string类型的变量都可以通过强制类型转换的语法欺骗编译器的强类型检查而作为PChar直接使用,如: PChar(s)。而且由于字串的长度存放在偏移-4处,因此求字串长度的时候速度极快,因为length(s) = PInteger(Integer(Pointer(s))-4)^,不用像PChar和array那样从头数到尾直到#0。那引用计数是干哈的呢?首先要明确一点,Delphi对于string是从堆中自动分配和释放内存,分配好说,但是什么时候释放呢?如果你了解COM的引用计数原理就知道,通过维护refCount系统就能够确定可以安全释放对象的时机了。因为Delphi对于string类型的字串使用了copy-on-write技术,因此如果简单的两个string都包含相同的内容,则实际上内存中仅有一份拷贝。如:
s1 := 'I love Delphi'; // line 1
s2 := s1; // line 2
s1 := s1 + '!'; // line 3
在第一行,Delphi将为s1分配内存并设定好负偏移处的长度信息与引用计数(初始为1);在第二行,事实上没有任何的内存分配操作,s2简单的被赋予s1的指针信息,同时他们指向的字串的引用计数+1(事实上Delphi程序内部还有一张表来记录这些引用信息和变量实例的关系);在第三行,s1进行了改变,根据内部的逻辑规则,Delphi将自动分配新的内存并实际拷贝s1+'!'的内容到新的内存中,然后改变s1的地址和s2指向字串的引用计数就搞定了。这就是所谓的copy-on-write。你说了,这没什么用啊,哪儿这么多直接的赋值啊?其实像返回字串的函数这类情况都能发挥copy-on-write的好处,经济、快速。综合一下,在Delphi编程中应该尽可能的使用string类型简化代码、减少出错并提高程序的运行效率。在调用C或者其他应用PChar的场合可以直接拿PChar(string)来用,不存在效率问题(因为只是强制转换而已)。字符数组主要用于定宽字串和定义结构时候用,不过只有下标为0且数组成员类型为char的array才和PChar兼容。
ftp://book:[email protected]/delphi5b3.rar