原文:
http://www.newlc.com/article.php3?id_article=12
字符串与描述符
发表于2003年12月16日,作者Eric Bustarret,
北京理工大学——陈罡译
对于初次接触Symbian平台的开发者来说,令他们非常惊讶的是——Symbian平台选择了不使用普通的数据类型和函数来处理字符串和二进制缓冲区的做法。这做法直接导致了不止一个开发人员花费了好几个小时的时间来弄清楚TBuf, TBufC, HBufC等等这些类的特殊之处以及各自的优缺点。
Symbian平台的主要的描述符的特点现归纳如下:
(1) 字符串和二进制数据采用相同的处理方法
(2) 数据可以被放置到任意的存储器中,无论是ROM还是RAM,也无论是在栈上还是在堆上。
(3) 每个描述符对象(descriptor object)都包含了指向数据的指针和该指针指向的数据的长度信息。一些描述符甚至包括了其最大可以容纳的数据长度。
下面的图例表示出了描述符类之间的派生层次关系,便于大家学习和理解:
所有的描述符都是从TDesC这个虚基类中派生出来的。这些描述符总的来说分为三种:
(1) 缓冲区描述符:这类描述符直接把数据存放在当前程序的堆栈里面,而且数据本身就是该描述符对象的一部分。典型例子是:TBuf类和TBufC类(注:由于普通Symbian的栈空间只有8K,因此这类描述符的大小最好要适量)
(2) 堆描述符:这类描述符将数据放置到当前程序的堆存储区内,和缓冲区描述符一样,数据本身也是该描述符对象的一部分。典型例子是:HBufC类(注:这类描述符由于是在堆上进行分配的,因此要求相对在栈上分配的描述符要宽松些,但是需要用户自己去管理该对象的生存期,否则可能在运行期间产生内存泄漏)。
(3) 指针描述符:这类描述符并不是把数据和描述符对象本身做为一体的,而只是保留了指向相应数据的指针而已。典型的例子是:TPtr类和TPtrC类
指针描述符可以用来等价替换经典C/C++中的以下两种类型:
a) TPtrC ——》 const char *
b) TbufC ——》char []
但是其他的类在经典C/C++中就没有相应的数据类型了。
下面的这副图就表示了在上述每个类中数据的组织形式:
TDes类和TDesC类是虚基类,所以你不能够直接将他们实例化。它们主要用于做为函数的形参,方便的操作字符串和二进制的数据。在这种类型的函数中,你可能会用到:
(1) const TDesC& 做为只读的字符串或二进制数据的传递
(2) TDes & 做为你需要修改的字符串或数据在函数间的传递
所有的描述符都有单位数据的宽度的限制,例如:TDes8,TDes16,TDesC8,TDesC16,TBuf8, TBuf16,等等,其中的后缀8代表了这个描述符是用来操作8位的数据的,而16则代表可以操作16位的数据内容。通常情况下,你可以使用更加自然的文本数据的表示形式:TDes,TDesC,(注:该定义将根据程序中是否预定义了_UNICODE常量,来自动将其转换成8位的或者16位的描述符),对于二进制数据则最好统一按照8位的来处理,如TDesC8。
字符串常量定义
字符串常量通常可以利用_L()宏和_LIT()宏来定义
_L()宏从常量字符串中可以得到TPtrC的指针,它在向一个函数传递字符串常量的时候尤其有用。例如:
NEikonEnvironment::MessageBox(_L("Error: init file not found!"));
_LIT()用于生成在程序中可以重复使用的、全局的常量字符串,并且可以为该字符串方面的命名。例如:
_LIT(KMyFile,"c://System//Apps//MyApp//MyFile.jpg");
上面这条宏的结果就是:KmyFile可以做为后面字符串的代替品,用在任何需要传入TDesC&参数的地方。
使用方法:
最常用的函数都定义在TDesC虚基类中。列举如下:
(1) Ptr()——用于得到指向描述符中数据的指针
(2) Length()——用于得到描述符中数据单位的长度(或者在存放字符串时表示字个数)
(3) Size()——用于以字节为单位表示描述符中数据的长度
(4) Compare()以及重载的==,!=,>=,<=用于描述符对象之间的比较
(5) 重载的[]运算符,用于从一个描述符中取出指定的一个数据单位,类似数组的使用方法
上述图中的许多函数都是可能有多种变体可以使用的:
(1) Append()和Num()一个是在当前描述符后面追加内容的文本内容的,另一个是追加数字(注:把数字直接转换成文本,然后追加进去)还有很多类似的常用函数的变体在这里就不一一列举了,具体的请参考Symbian Developer Library。
(2) Compare()函数也有很多变体例如CompareC()和CompareF()函数,以及含有类似变体的Copy(),Find(),Locate()和Match()所有这些函数都有C和F扩展变体,分别代表了核对方式(collated)和合并方式(folded)的意思。
核对方式(Collated)和合并方式(Folded)的含义:
合并是一种相对简单的忽略重音的方法处理字符串,然后比较。主要用于完成不精确的操作。例如将字符串中的所有重音的地方变成没有重音的单词。
核对则是一种更好的同时也更强大的字符串处理方式,采用类似字典排序的方式。例如对于使用拉丁文的字符串脚本,它可以自动决定是否忽略标点符号,忽略重音,忽略大小写等等。
字符串与描述符
发表于2003年12月16日,作者Eric Bustarret,
北京理工大学——陈罡译
对于初次接触Symbian平台的开发者来说,令他们非常惊讶的是——Symbian平台选择了不使用普通的数据类型和函数来处理字符串和二进制缓冲区的做法。这做法直接导致了不止一个开发人员花费了好几个小时的时间来弄清楚TBuf, TBufC, HBufC等等这些类的特殊之处以及各自的优缺点。
Symbian平台的主要的描述符的特点现归纳如下:
(1) 字符串和二进制数据采用相同的处理方法
(2) 数据可以被放置到任意的存储器中,无论是ROM还是RAM,也无论是在栈上还是在堆上。
(3) 每个描述符对象(descriptor object)都包含了指向数据的指针和该指针指向的数据的长度信息。一些描述符甚至包括了其最大可以容纳的数据长度。
下面的图例表示出了描述符类之间的派生层次关系,便于大家学习和理解:
所有的描述符都是从TDesC这个虚基类中派生出来的。这些描述符总的来说分为三种:
(1) 缓冲区描述符:这类描述符直接把数据存放在当前程序的堆栈里面,而且数据本身就是该描述符对象的一部分。典型例子是:TBuf类和TBufC类(注:由于普通Symbian的栈空间只有8K,因此这类描述符的大小最好要适量)
(2) 堆描述符:这类描述符将数据放置到当前程序的堆存储区内,和缓冲区描述符一样,数据本身也是该描述符对象的一部分。典型例子是:HBufC类(注:这类描述符由于是在堆上进行分配的,因此要求相对在栈上分配的描述符要宽松些,但是需要用户自己去管理该对象的生存期,否则可能在运行期间产生内存泄漏)。
(3) 指针描述符:这类描述符并不是把数据和描述符对象本身做为一体的,而只是保留了指向相应数据的指针而已。典型的例子是:TPtr类和TPtrC类
指针描述符可以用来等价替换经典C/C++中的以下两种类型:
a) TPtrC ——》 const char *
b) TbufC ——》char []
但是其他的类在经典C/C++中就没有相应的数据类型了。
下面的这副图就表示了在上述每个类中数据的组织形式:
TDes类和TDesC类是虚基类,所以你不能够直接将他们实例化。它们主要用于做为函数的形参,方便的操作字符串和二进制的数据。在这种类型的函数中,你可能会用到:
(1) const TDesC& 做为只读的字符串或二进制数据的传递
(2) TDes & 做为你需要修改的字符串或数据在函数间的传递
所有的描述符都有单位数据的宽度的限制,例如:TDes8,TDes16,TDesC8,TDesC16,TBuf8, TBuf16,等等,其中的后缀8代表了这个描述符是用来操作8位的数据的,而16则代表可以操作16位的数据内容。通常情况下,你可以使用更加自然的文本数据的表示形式:TDes,TDesC,(注:该定义将根据程序中是否预定义了_UNICODE常量,来自动将其转换成8位的或者16位的描述符),对于二进制数据则最好统一按照8位的来处理,如TDesC8。
字符串常量定义
字符串常量通常可以利用_L()宏和_LIT()宏来定义
_L()宏从常量字符串中可以得到TPtrC的指针,它在向一个函数传递字符串常量的时候尤其有用。例如:
NEikonEnvironment::MessageBox(_L("Error: init file not found!"));
_LIT()用于生成在程序中可以重复使用的、全局的常量字符串,并且可以为该字符串方面的命名。例如:
_LIT(KMyFile,"c://System//Apps//MyApp//MyFile.jpg");
上面这条宏的结果就是:KmyFile可以做为后面字符串的代替品,用在任何需要传入TDesC&参数的地方。
使用方法:
最常用的函数都定义在TDesC虚基类中。列举如下:
(1) Ptr()——用于得到指向描述符中数据的指针
(2) Length()——用于得到描述符中数据单位的长度(或者在存放字符串时表示字个数)
(3) Size()——用于以字节为单位表示描述符中数据的长度
(4) Compare()以及重载的==,!=,>=,<=用于描述符对象之间的比较
(5) 重载的[]运算符,用于从一个描述符中取出指定的一个数据单位,类似数组的使用方法
上述图中的许多函数都是可能有多种变体可以使用的:
(1) Append()和Num()一个是在当前描述符后面追加内容的文本内容的,另一个是追加数字(注:把数字直接转换成文本,然后追加进去)还有很多类似的常用函数的变体在这里就不一一列举了,具体的请参考Symbian Developer Library。
(2) Compare()函数也有很多变体例如CompareC()和CompareF()函数,以及含有类似变体的Copy(),Find(),Locate()和Match()所有这些函数都有C和F扩展变体,分别代表了核对方式(collated)和合并方式(folded)的意思。
核对方式(Collated)和合并方式(Folded)的含义:
合并是一种相对简单的忽略重音的方法处理字符串,然后比较。主要用于完成不精确的操作。例如将字符串中的所有重音的地方变成没有重音的单词。
核对则是一种更好的同时也更强大的字符串处理方式,采用类似字典排序的方式。例如对于使用拉丁文的字符串脚本,它可以自动决定是否忽略标点符号,忽略重音,忽略大小写等等。