symbian RBuf浅析
时间:2010-06-04 来源:freebendy
概述
Resizable buffer描述符是一个RBuf类型。这个描述符是最近才添加到描述符大家庭的,和其他描述符类型一样,用于包含字符串和二进制数据。通过这个描述符继 承基类的成员函数可以访问和修改数据,描述符的数据分配在堆上,但数据不属于描述符的一部分。
一般的用法是:当很少修改数据时,使用HBufC类型;当需要频繁修改数据时,使用RBuf类型。然而,在实际中RBuf同时适用于这两种情况,并且应该 优先使用RBuf类型。
关于描述符的一些重点:
对于文本数据,常用RBuf类型;对于二进制数据,显式使用RBuf8类型;极少显式使用RBuf16类型。数据据能够通过RBuf和赋值操作符进行修 改。在传递参数时,可以向形参为TDesC&和TDes&类型的函数传递RBuf类型。代码中已经分配的内存可以转移给RBuf,这允许 任何区域的内存能够通过RBuf进行操作。已经存在的HBufC对象的所有权也能转移给RBuf。这允许包含在HBufC中的数据可以通过RBuf操作。
创建RBuf
RBuf对象可以在栈上创建,也可以作为‘C’类型类的成员函数,但不能作为‘T’类型类的成员函数。
IMPORT_C RBuf();
缺省的构造函数没有分配缓冲区,意味着对象没有数据,描述符的长度和最大长度都是0。
在描述符处理数据之前,必须要创建缓冲区。
1、最简单创建RBuf方法:
IMPORT_C TInt Create(TInt aMaxLength);
IMPORT_C void CreateL(TInt aMaxLength);
参数指定了创建缓冲区的最大长度,但描述符的数据为空,长度为0。
IMPORT_C TInt CreateMax(TInt aMaxLength);
IMPORT_C void CreateMaxL(TInt aMaxLength);
参数指定了创建缓冲区的最大长度,同时将数据长度也设置为同一个值,缓冲区中数据将添加任意值。
2、通过已存在的描述符创建RBuf:
IMPORT_C TInt Create(const TDesC &aDes);
IMPORT_C void CreateL(const TDesC &aDes);
创建一个缓冲区,将指定的已存在的描述符对象的数据复制到缓冲区中。RBuf的最大长度和长度与指定的描述符一致。
IMPORT_C TInt Create(const TDesC &aDes, TInt aMaxLength);
IMPORT_C TInt CreateL(const TDesC &aDes, TInt aMaxLength);
创建一个缓冲区,将指定的已存在的描述符对象的数据复制到缓冲区中。当复制的数据长度小于aMaxLength时,将完全复制,RBuf的长度为描述符的 长度;当大于时,将部分复制,RBuf的长度为aMaxLength。
3、通过将已分配内存的所有权转移来创建RBuf:
一个创建RBuf的重要技术就是将已分配的内存的所有权转移给RBuf。这意味着允许RBuf能处理任何内存区域。
1)转移HBuf的所有权给RBuf:
IMPORT_C RBuf(HBufC *aHBuf);
通过构造函数来获得HBuf的所有权。
IMPORT_C void Assign(HBufC *aHBuf);
在创建了RBuf对象后,通过成员函数来获得HBuf的所有权。
一旦转移了所有权,就不能通过HBuf对数据进行访问了。而释放内存也必须由RBuf来完成。
2)转移已分配内存的所有权给RBuf:
IMPORT_C void Assign(TUint *aHeapCell, TInt aMaxLength);
IMPORT_C void Assign(TUint *aHeapCell, TInt aLength, TInt aMaxLength);
3)转移另一个RBuf对象的所有权给当前RBuf:
IMPORT_C void Assign(const RBuf &aRBuf);
重新分配缓冲区
IMPORT_C TInt ReAlloc(TInt aMaxLength);
IMPORT_C void ReAllocL(TInt aMaxLength);
无论初始的缓冲区是分配的还是通过转移所有权来的,都可进行重新分配。但重新分配的最大长度不能小于数据长度。
释放缓冲区
当已分配的RBuf对象不在使用时,必须释放分配的缓冲区,防止内存泄漏。可以使用ReAlloc(0)和 ReAllocL(0)函数传递参数零来释放缓冲区内存。
IMPORT_C void Close();
标准的释放内存的成员函数,将已分配的内存释放,并将描述符的长度设为0。
清理规则
当RBuf对象分配在栈上时,为了防止在分配堆缓冲区异常退出而导致内存泄漏,需要在分配堆缓冲区前将RBuf对象推入清理栈中。当描述符对象异常退出 时,调用Close()释放缓冲区。最后需要将RBuf对象从清理栈中弹出。
IMPORT_C void CleanupClosePushL();