Symbian基礎總結 -- 描述符簡介

 本文出處:http://www.cnblogs.com/felixYeou/archive/2008/11/05/1327660.html

 

一、強化印象
在學習描述符之前,首先要理解Symbian中描述符的作用。在Symbian中,沒有提供專門用來處理字符串的類,它把字符串和二進制緩衝區看成是同一類數據,有一套專門的類去管理,這一套類的類關係圖層次結構如下圖所示:

symbian_desc_1.gif

圖一. 描述符類的層次關係

上圖所示的類統稱爲“描述符”,Symbian用“描述符”來管理字符串,其中,TDesC、TDes、TBufCBase爲抽象類。
我們首先來舉一個簡單的例子,來強化我們對描述符的理解。如果我們由一個字符串“NewLC”,我們想使用變量存放,在C語言中,我們可以使用如下代碼編寫:

1
2
char[] c = “NewLC”;
const char* c = “NewLC”;

而在Symbian C++中,我們應該使用以上那個描述符存放呢?
答案是:你可以使用任一描述符存放!我們不給代碼,先向大家展示一下使用不同的描述符存放字符串在內存中的存放形式:

symbian_desc_1.gif

圖二. 描述符對象與數據在內存中的位置

二、理解概念

1、根據描述符數據存放位置進行分類(如圖二):

  • 棧描述符TBuf和TBufC:數據做爲描述符對象的組成部分而存在,描述符對象存放在程序的棧中,就像C語言中的字符數組(char[])。
  • 堆描述符HBufC:數據做爲描述符對象的組成部分而存在,描述符對象存放在堆中,就像C語言中的(char*)malloc( length+1 )一樣通常用於預先不能確定長度的情況。因爲是在堆上分配的,它總是通過HBufC*使用而不是直接定義HBufC對象。
  • 指針描述符TPtr和TPtrC:描述符對象和它所表示的實際數據是分開存放的,描述符對象存放在棧中,正如“指針”的含義,指針描述符所指向的數據可以爲棧中的數據,也可爲堆中的數據。TPtrC和TPtr與C語言中的char*有點兒類似,但因爲描述符自己包含了長度信息,所以不再需要掃描結尾的空字符(‘/0’)或爲它分配空間。

2、可修改的描述符與不可修改的描述符:
大家可以看到,在描述符類中,有些類結尾帶“C”,這些類表示“只讀的描述符”,即:描述符在定義時擁有的數據或指向的數據,描述符不提供修改的方法。所以,推薦使用以下方法聲明可修改的描述符和不可修改的描述符:

1
2
const TDesC& str;
TDesC& str;

可以從圖一看到,基類TDesC沒有提供對內容修改的函數,而繼承自TDesC的類TDes提供了對內容修改的函數。

3、描述符的寬度
所有這些描述符都可以指定數據尺度:TDes8、TDes16、TDesC8、TDesC16、TBuf8、TBuf16等
這裏8表示描述符處理的數據是8bit的,而16表示是16bit數據。一般來說,你只要使用通用形式(TDes, TDesC,…)來表示文本數據而使用8bit版本(TDesC8等)來表示二進制的內容。

三、描述符的使用
1、使用宏_LIT(_LIT16,_LIT8)和_L定義字符串常量
_L()可以生成一個指向字符值的地址(TPtrC),它經常被用來傳遞字符串到函數中:

1
NEikonEnvironment::MessageBox(_L(“Error:  init  file  not  found!));

_LIT()可以生成個常量名,以便以後重複使用:

1
_LIT(KMyFile, “c:/System/Apps/MyApp/MyFile.jpg);

_LIT()宏的結果(就是上面的KMyFile)實際上是個文字描述符(literal descriptor)TLitC,它可以在任何使用TDesC&的地方使用。

2、系統定義的描述符
KNullDesC(KNullDesC16, KNullDesC8)

1
_LIT16(KNullDesC, "");

表示空或者無文本的16位(8位)格式描述符。

3、構造描述符

  • TBufC(不可修改的棧描述符)
    1
    2
    3
    4
    5
    6
    7
    _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(可修改的棧描述符)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);
    ...
    // 我們能夠使用buf做一些事情,如:將buf寫入文件或者通過Socket發送
  • TPtrC(不可修改的指針描述符)
    1
    2
    3
    const unsigned char KBuffer[] = {0x00, 0x33, 0x66, 0x99, 0xbb, 0xff};
    TPtrC8 bufferPtr( KBuffer, sizeof(KBuffer));
    iSocket.Write(bufferPtr, iStatus);
  • TPtr(可修改的指針描述符)
    1
    2
    3
    4
    5
    6
    7
    _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"
  • HBufC(堆描述符)
    1
    2
    3
    HBufC* heapBuf = HBufC::NewL(KHelloWorld().Length());

    *heapBuf = KHelloWorld();
    delete heapBuf;

4、使用描述符

  • Ptr(),用來獲得描述符數據中的指針。
  • Length(),用來獲得描述符數據中的字符數。
  • Size(),用來獲得描述符數據中的字節數目。
  • Cpmpare()或操作符==、!=、<=和>=等專爲比較描述符數據用的。
  • 操作符[],可以被當作c/c++中一樣,用來獲得描述符字符串中的單個字符。
  • Append()和Num()有很多重載形式,具體可以看SDK
  • Compare()有2個變體:CompareC()和CompareF(),以及Copy(),Find(),Locate()和Match(),這些函數都有C/F的後綴形式,C代表Collated而F代表Folded。Folding是個比較格式化文本的簡單方法,主要用在對比較不是太要求精確的場合。Collation是個更好的也更有效的比較字符串的方法,可以生成類似字典的順序。

四、參考文獻:
1.《Symbian中的String和Descriptors》,出處:http://blog.csdn.net/sworder_001/archive/2006/09/27/1297069.aspx
2.《描述符淺析》,出處:http://blog.csdn.net/btooth/archive/2006/07/05/879584.aspx
3.《Symbian基本規範:描述符》,出處:http://gardenlee.blogchina.com/gardenlee/3285302.html
4.《Nokia官方培訓(Symbian4300)筆記(六)—Descriptors》,出處:http://embed.e800.com.cn/articles/2007/427/1177655438529691221_1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章