呵呵,pchar是指向以null结尾的char字符串的指针,在调用winapi的时候最好用这种。
解决方案 »
- 请问一个多重接口继承问题
- 如何创建IE工具条,请高手指点下面的代码?
- 如何判断inputbox是点击的ok还是cancel?
- 我想为FindDialog的OnFind找文本,怎么写?
- 如何判断dbchart中的某条线是否存在,若则把这条线取消,应该怎么做啊(这些都需用代码动态实现),在线急急急啊
- 图像拷贝。
- 是重庆的Delphi程序员,请进来
- 一个简单但棘手的问题,请同志们近来,我保证进来的都有分
- 关于证券之星的编程(超级难题)
- 关于ORACLE的问题
- 请问如何安装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