描述符 HBufC 与 TPtr 练习
通过 HBufC 的操作也了解了 TPtr 的操作,TPtr 可以修改 HBufC 的值,重新分配不会改变已有值及首地址更正:ReAllocL 是重新分配方法,重新分配后,首地址不变 有误,正确为重新分配后,有可能地址会和原来的一样,每次重新分配后要进行 pop 原来的,再 pushL 新的,下面是练习代码
_LIT(KTxtHelloworld,"Hello World");
_LIT(KTxtHelloworldMorning,"Hello World morning"); _LIT(KTxtAndHi," & Hi");
_LIT(KCommonFormat1,"Size()=%d \n MaxLength()=%d\n");
_LIT(KCommonFormat2,"Ptr()=%x \n Length()=%d \n"); _LIT(KCommonFormat5,"Prt()=%x \n Length()=%d \n Size()=%d\n");
// Global Variables
LOCAL_D CConsoleBase* console; // write all messages to this
// Local Functions
LOCAL_C void MainL(const TDesC& aArgs)
{ // // add your program code here, example code below // //console->Write(_L("Hello, world!\n")); HBufC* buf; buf = HBufC::NewL(15); // 上面是定义一个 HbufC 对像指针 // 了解一下 HBufC 的继承关系 TDesC->TBufCBase->HBufC // ->TBufC // TDesC->TPtrC // TDesC->TDes->TBufBase->TBuf // ->TPtr // 注意:HBufC 不会在栈上实例化,只能在堆上实例化 // Prt() 返回描述符的数据缓冲器 // %x 比 Prt() 小 4 个字节,也就是说描述符的数据缓冲器在 HBufC 指针起始位置的4四个字节开始 // 如果不做任何的初始化 Length() 及 Size()返回的是 0 CleanupStack::PushL(buf);
_LIT(KFormat10,"\"%S\" desc at %X; ");
console->Printf(KFormat10,buf,buf); console->Printf(KCommonFormat5,buf->Ptr(),buf->Length(),buf->Size()); *buf = KTxtHelloworld; _LIT(KFormat9,"\"%S\""); console->Printf(KFormat9,buf); console->Printf(KCommonFormat5,buf->Ptr(),buf->Length(),buf->Size()); /* 上面的代码把 HelloWorld 赋给 buf ,然后显示 buf 的内容、描述符缓冲器、 长度、大小
%s 与 %S 具体区别还不清楚,不过这里的 %s 不会显示内容,而%S能显示内容
%x 与 %X 没有区别
Length() = 11 hello world 正好是 11 个字符
Size() = 22 对于 size 的解释:如果是16位的描述符,则 size=length*2 如果是8位的,则 size=length 所以这里的 22 成立 */
buf = buf->ReAllocL(20);
*buf= KTxtHelloworldMorning; console->Printf(KFormat9,buf); console->Printf(KCommonFormat5,buf->Ptr(),buf->Length(),buf->Size()); /* 上面的代码把 buf 重新分配为 20 个字节大小的 HBufC 注意:如果将 *buf= KTxtHelloworldMorning; 去掉,则 buf 的内容不变,还是 Hello world
如果重新分配 buf = buf->ReAllocL(9); 小于目前的大小,则程序出错
如果重新分配 buf = buf->ReAllocL(18); 小于赋给的描述符的大小,则程序出错 */ buf = buf->ReAllocL(22); _LIT(KFormat6,"\"%S\"; \n(2nd realloc) \ndesc at:%x"); console->Printf(KFormat6,buf,buf); console->Printf(KCommonFormat5,buf->Ptr(),buf->Length(),buf->Size()); /* 上面有代码又显示了 buf 的地址,虽然经过了两次的重新分配,但起始地址并没有改变 */
TPtr ptr=buf->Des();
_LIT(KFormat11,"TPtr desc at:%x;\n"); console->Printf(KFormat11,&ptr); console->Printf(KCommonFormat2,ptr.Ptr(),ptr.Length()); console->Printf(KCommonFormat1,ptr.Size(),ptr.MaxLength()); /* 上面的代码通过 HBufC 的 des 返回一个 TPtr 对像, 分配的 TPtr 地址与 buf 不一样,但都指向同一内存地址 ,也就是 Ptr() 的值相同 MaxLength() = 分配的长度 22 */
ptr.Delete(ptr.Length()-9,9);
ptr.Append(KTxtAndHi); _LIT(KFormat4,"\n\"%S\";\nHBufC desc at %x;\n"); console->Printf(KFormat4,buf,buf); console->Printf(KCommonFormat5,buf->Ptr(),buf->Length(),buf->Size()); /* 从上面的代码中可以看到 通过 TPtr 对像可以改变 HBufC的对像值,同时改变 length() 及 Size() 的结果
新学两个函数
delete 及 append 注意:delete 是从第几位开始删除几个字符,基于 0 索引的,删除的字符包括起始位置 的字符 */
_LIT(KFormat3,"\"%S\";\n TPtr desc at %x;\n");
console->Printf(KFormat3,&ptr,&ptr); console->Printf(KCommonFormat2,ptr.Ptr(),ptr.Length()); console->Printf(KCommonFormat1,ptr.Size(),ptr.MaxLength()); /* Length() 及 size() 会发生变化,MaxLength 不会变化 %x 取得值与 改变 ptr 值前没有变化 */
//
CleanupStack::PopAndDestroy(); console->Printf(_L("Command line args: \"%S\"\n"), &aArgs); } |
总结一下:
- HBufC 只能在堆中分配内存空间
- 描述符的继承关系为
TDesC->TBufCBase->TBufC
->HBufC
->TPtrC
->TDes->TBufBase->TBuf
->TPtr -
ReAllocL 是重新分配方法,重新分配后,首地址不变,已有内容不会清除,会保存已有内容,Length 及 Size 会有变化
重新分配时不能小于现有大小,否则程序出错
更正:ReAllocL 是重新分配方法,重新分配后,首地址不变 有误,正确为重新分配后,有可能地址会和原来的一样,每次
重新分配后要进行 pop 原来的,再 pushL 新的,如下代码:HBufC* buf = HBufC::New(15);
_LIT(Kfmt,"%X\n");
CleanupStack::PushL(buf);
_LIT(KText,"YunYun\n");
*buf = KText;
console->Write(*buf);
console->Printf(Kfmt,buf);console->Printf(Kfmt,buf->Ptr());
buf = buf->ReAlloc(20);
CleanupStack::Pop(buf);
console->Printf(Kfmt,buf);
console->Printf(Kfmt,buf->Ptr());
CleanupStack::PushL(buf);
_LIT(KRepText,"&YunYun&&YunYun&\n");
*buf = KRepText;
console->Write(*buf);
CleanupStack::PopAndDestroy(buf); -
TPtr 对像可以通过 Des() 方法得到,这样可以对 HBufC 的值进行修改,TPtr与HBufC的 Ptr() 描述符缓冲器相同,是指
向同一内存地址的
有 delete 方法及 append
delete时从指定位置起删除指定长度的字符,删除包括指定位置的字符,索引是基于 0 的
append 很简单,但添加后的总长度不能大于MaxLength 的长度,也就是分配时指定的长度 -
改变后 ,HBufC对像及TPtr的 Length 及Size 会有变化 ,TPtr 的 MaxLength 不会变化,HbufC及TPtr 的首地址不会变化
-
_LIT 的使用
-
console->printF 的使用,参数
%S 是取内容 区分大小写
%d 是十进制 ,不区分大小写
%x 是十六进制,不区分大小写 -
对于 HBufC16及HBuf8的 Length 及 Size 的返回
HBufC16 的 Length*2 = Size
HBufC8 的 Length = Size
安平2009@原创
qi_jianzhou@126.com