诺基亚symbian 手册汇编2

Introduction    描述符(Descriptors)封装了字符串和二进制数据,用于替代C中的以NULL结尾的字符串。它的长度和数据都封装在了描述符中,Symbian API中用的都是描述符。如:

    TPtrC ptr (KHelloWorld);    CEikonEnv::Static()->InfoMsg(ptr);

Main Types of Descriptors

    主要可以分为以下几类,其中带C的是不可修改的。


Abstract:(TDes、TDesC),其他描述符的基类,不能实例化,一般用作函数的参数。
Literal:(TLitC,_LIT()),用于存储literal string,一般使用后者。
Buffer:(TBuf,TBufC),数据存储于栈上,大小在编译时确定。
Heap:(HBufC),数据存储于堆上,大小在运行时确定。
Pointer:(TPtr,TPtrC),引用存储于类之外的数据
Descriptor Modification    描述符可以是可修改的和不可修改的,通常带C的都是不可修改的,不可修改的是可修改的基类。   


Moidfiable:提供了访问和修改数据的API,如TBuf
Non-Modifiable:数据只可以被访问,不可修改。但是通过Des()函数可返回一个可修改的指针
Descriptor Width    在描述符类后加上8或者16影响了存储在描述符中的数据的宽度,默认是16位的,处理二进制或ASCII时采用8位。


8位:(TDesC8),用于二进制数据或者ASCII字符串
16位:(TDesC16),默认,Unicode
下面开始对上述5类描述符进行详细介绍,首先看一下类继承关系

 

这里显示的是8位的,16位默认的类继承关系与此一致

Abstract Descriptors    除Literal外的所有描述符的基类,提供了基本的接口和基础功能。他们本身不能实例化,一般用作函数参数。

TDesC:提供了比较、复制、搜索、提取部分字符串的函数。

TInt TDesCUtil::SumLengths(const TDesc& aDesC1, const TDesc& aDesC2)

{

   return aDesC1.Length() + aDesC2.Length();

TDes:继承自TDesC,添加了许多用于修改数据的函数。其最大长度是描述符被创建时确定的。

TInt TDesCUtil::AppendL(TDesc& aTarget, const TDesc& aDesC)

{

   TInt sumLen = aTarget.Length() + aDesC.Length();

   if (aTarget.MaxLength() < sumLen)

   {

      User::Leave(KErrOverflow);

   }

   aTarget.AppendL(aDesC);

}

Literal Descriptors    提供了一种将字符串放在只读存储空间中的机制(实际存放在程序的数据区,而不是真的在ROM中)。一般不采用TLitC而直接采用_LIT()宏。    _LIT(KHelloWorld, "Hello World!");

    通过()操作符可以得到 const TDesC&。 TInt length = KHelloWorld().Length();

    在函数参数为const TDesC&可以直接使用KHelloWorld。iLabel->SetTextL(KHelloWorld);

Buffer Descriptors

    将数据作为本身的一部分存储在stack上,他们的最大长度是在编译时确定的。 

TBuf<16> helloWorld = KHelloWorld;

TInt len = KHelloWorld().Length();

helloWorld[len-1]='?';

在内存中如下所示:

 

TBufC的用法如下:

_LIT(KHelloWorld, "Hello World");

const TInt maxBuf = 32;

TBufC<maxBuf> buf;

TInt currentLen = buf.Length(); // == 0

buf = KHelloWorld;

currentLen = buf.Length(); // == 11

TText ch = buf[2]; // == 'l'

TBuf的用法如下:

const TInt bufLen = 6;

TUInt8 objType = 1;

TUInt8 objId = 1;

TUInt8 xCoord = 128;

TUInt8 yCoord = 192;

....

TBuf8<bufLen> buf;

buf.Append(objType);

buf.Append(objId);

...

//we can now do something with the buffer such as writting it to a binary file or send via socket.

Pointer Descriptor    用于引用存储在其他地方的数据,如:

const unsigned char KBuffer[ ] = {0x00, 0x33, 0x66, 0x99, 0xbb, 0xff};

TPtrC8 bufferPtr( KBuffer, sizeof(KBuffer));

iSocket.Write(bufferPtr, iStatus);

在内存中如下所示:

 

 


TPtr的用法:

_LIT(KHelloWorld, "Hello World");

const TInt maxBuf = 32;

TBufC<maxBuf> buf;

buf = KHelloWorld;

TPtr ptr = buf.Des();

ptr[7] = 'a';  ptr[8] = 'l';  ptr[9] = 'e';  ptr[10] = 's'; 

CEikonEnv::Static()->InfoMsg(ptr); // "Hello Wales"

Heap Descriptors

     动态在堆(heap)上分配,通过HBufC的API,数据可以被set和reset,但是不能被修改。如:

HBufC* heapBuf = HBufC::NewL(KHelloWorld().Length());

*heapBuf = KHelloWorld();

delete heapBuf;

     在内存中的情况如下图所示:

 

    HBufC通常在以下几种情况下使用:


在运行时从资源文件中加载字符串
从用户界面中接收用户输入的字符串
从应用程序引擎中接收字符串,如contacts database中的名字

     对HBufC中的内容进行修改:

_LIT(KHello, "Hello!");

_LIT(KWorld, "World!");

HBufC* heapBuf = HBufC::NewL(KHello().Length());

*heapBuf = KHello;    //buf holds "Hello!"

heapBuf = heapBuf->ReAllocL(KHello().Length() + KWorld().Length());

CleanupStack::PushL(heapBuf);

TPtr ptr (heapBuf->Des());  //DON'T use TPtr ptr = heapBuf->Des(); this will set maxlen to 6 but not 12...

ptr[KHello().Length() - 1] = ' ';

ptr += KWorld;

iTopLabel -> SetTextL(ptr);

CleanupStack::PopAndDestroy();

DrawNow();

下面介绍Descriptors的具体用法:

Non-Modifying Methods     Length(),Size(),Left(),Right(),Mid(),Compare(),Locate(),LocateReverse(),Find(),Match()等。以下代码示例描述了如何在一个descriptor中找到<>中的内容,如果不存在,返回整个字符串:

static const TUint KAddressStartChar = '<';

static const TUint KAddressEndChar = '>';

TPtrC ExtractAddressNumber( const TDesC& aAddressString)

{

    TInt addrStart = aAddressString.Locate(KAddressStartChar ) + 1;

    TInt addrEnd  = aAddressString.LocateReverse(KAddressEndChar ) ;

    if ((addrStart == KErrNotFound) || (addrEnd == KErrNotFound) || (addrStart >= addrEnd) )

    {

        addrStart = 0;

        addEnd    = aAddressString.Length();

    }

    return (aAddressString.Mid(addrStart, (addrEnd - addrStart) ) );

}

Modifying Methods     Zero(),Copy(),Num(),Format(),Insert(),Replace(),Delete(),Append(),Trim()等。代码示例:

_LIT(KText, "Hello World!");

_LIT(KNewText, "New Text");

_LIT(KReplaced, "Replaced");

TBuf<16> buf1(KText);

buf1.Delete(6, 6); // length is now 6, leaving "Hello" in the buffer

TBuf<16> buf2(KNewText);

buf2.Copy(KReplaced); // buf2 now contains "Replaced"

buf2.Append(KNewText);  //buf2 now contains "Replaced New Text"

buf2.Delete(99, 1); //Will Cause a PANIC!!!

Descriptors in Method Declarations

在函数参数中尽量使用基类
使用中性的描述符,一般情况下使用TDesC而不是TDesC8或者TDesC16
当描述符内容不应该改变时,使用const修饰符
经典用法:void SetText(const TDesC& aText);    TPtrC Text() const;

  Character Conversions        CCnvCharacterSetConverter类提供了在Unicode和其他字符集编码之间转换的方法。

ASCII本来就是Unicode的一个子集,无须使用该类。和Unicode之间的转换方法如下所示:

TBuf16<64>  UnicodeBuf;

_LIT8(KAsciiStr, "Hello");

UnicodeBuf.Copy(KAsciiStr);

Unicode和拉丁语系之间的转化可使用如下的代码:

TBuf8<64> Latin1Buf;

_LIT16(KUnicodeStr1, "hello");

_LIT16(KUnicodeStr2, "I have got 10\x20AC.");  //\x20AC is a euro

Latin1Buf.Copy(KUnicodeStr1); //OK

Latin1Buf.Copy(KUnicdoeStr2); //Not as you wanted.

待补充:Unicode和中文之间的转化

读后感对于初学者来说,一开始这部分是最难接受的,因为都已经习惯了C中的字符串。

但是经过一段时间的适应后,会慢慢熟悉它,这种东西要看好多遍才能领会,这个培训教程确实很好,讲的非常清楚。

多看看Forum Nokia上的例子和如InternetRadio等开源代码,慢慢的,你就适应了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值