初學symbian 一路走來

// -----------------------------------------------------------------

 

//

// 這是我的第二篇博文,開始學習Symbian c++

// 同大家一起努力

// 謹以此文獻給我的最愛 YY女孩(YY 可別想壞了哦)

//

// -----------------------------------------------------------------

 

 

每一個初學Symbian c++的同學肯定和我一樣迷茫,那我們就一起來學習吧!

我用的環境是Carbide c++V2.0

其實個人認爲Symbian最難入門的是那些從來沒見過的數據類型,非常頭痛,下面是我找到的數據類型

 

 

 

 

表2-1  Symbian OS的基本數據類型

發現下面這些數據都是T開頭的,對了學習SC++,對考都和結尾要留心

數 據 類 型

描    述

C++內置類型

TInt

有符號整數。在所有實現中保證數據至少爲32位

signed int

TUint

無符號整數。在所有實現中保證數據至少爲32位

unsigned int

TInt32、TInt16、
TInt8

32位、16位和8位的有符號整數

long int、short int、singed char

   

 

 

 

TUint32、TUint16

TUint8

32位、16位和8位的無符號整數

unsigned long int、unsigned short int、unsigned char

TInt64

64位整數

long long

TUint64

64位無符號整數

unsigned long long

TText

文本型,又細分爲TText8和TText16,內部引用都是TText16

unsigned short int

TText8

TText16

8位和16位無符號文本

unsigned short int

unsigned char

TReal32

32位浮點數

float

TReal、TReal64

64位浮點數

double

TBool

布爾型

int (這裏是Int ?)

TAny

指針型

void

 

如果想了解更仔細請參考 http://book.csdn.net/bookfiles/1240/100124036909.shtml

 

 

除了以上的基本數據類型,SC++中的String型也是攔路虎之一;

描述符 SC++中的String型

描述符是 Symbian OS中用到的字符串類。之所以這樣稱呼它們,是因爲它們是自描述的字符串。也就是說,描述符不僅包含它所描述的字符串數據的長度,還包含了類型信息,以區分描述符數據在內存中不同的結構。描述符可以防止緩存溢出,它並不使用NULL結束符作爲字符串的結尾。(這個也是c++的特點,C中纔會有NULL來結束)

描述符的應用從最底層向上貫穿於整個操作系統,而且它們被設計得非常有效率,使用最小的內存空間但又足夠存儲數據,並同時可以全面描述其長度和位置。描述符可作爲字符串幷包含字符數據。同時它們還可以用來操作二進制數據,因爲它們不需要用NULL作爲結尾字符來確定長度。

表3-2  對描述符類型的總結

名    稱

是否可修改

等 價 C

類    型

說    明

TDesC

n/a

不可實例化

其他所有描述符的基類(字面描述符除外)

TDes

n/a

不可實例化

所有可修改描述符的基類

TPtrC

const char*

(數據不被描述符所

“擁有”)

指針

數據與描述符是分開存儲的,即描述符並不知道數據的存儲位置

TPtr

char *

(數據不被描述符所

“擁有”)

指針

數據與描述符是分開存儲的,即描述符並不知道數據的存儲位置

TBufC

可間接修改

const char[]

棧緩存

瘦模板的大小在編譯時才確定

TBuf

const[]

棧緩存

瘦模板的大小在編譯時才確定

HBufC

可間接修改

const char*

(可“擁有”數據)

堆緩存

用於修改頻繁的動態數據存儲

RBuf

char*

(可“擁有”數據)

堆緩存

用於可修改的動態數據存儲

TLitC

static const char[]

字面描述符

構建在ROM裏

  在命名這些類時,以T爲前綴的說明這是一個簡單類型的類,而以C爲後綴的則說明此類定義了一個不可改變的描述符類型——也就是其內容是常量
 
  TDesC 提供了查詢描述符長度(Length())以及取得其中數據(Ptr())的方法。在使用這些方法時,它同時還實現了所有常量字符串對象所需的標準操作,比如訪問數據、比較和查詢。派生類繼承了所有這些方法,並且無論以何種方式繼承,所有常量描述符的操作都是由TDesC來實現的。除了字面描述符外, Symbian OS所有其他的描述符類都繼承自基類TDesC。
 
   TDes  所有可變的描述符類都從基類TDes派生,而 TDes本身也是TDesC的子類。TDes存儲了已分配給描述符的當前內存數據的最大長度。這個數值可由TDes的MaxLength()方法返回。同 TDesC的Length()方法一樣,此方法不能被其派生類所重寫。描述符內容的長度可以在此值的限定範圍內增加或減小。

TDes定義了一組操作可變字符串數據的方法,包括那些對描述符進行擴充、填充以及格式化的操作。所有改變描述符的操作代碼都由TDes來實現,並且可被其派生類繼承。在Symbian Developer Library(這個書友誰可以給個連下載下,謝謝)裏有對可變及不可變描述符的基類API方法進行全面描述的相關文檔。

    描述符基類TDesC和TDes實現了所有通用的描述符操作代碼,但是它們不能被實例化。

 

  指針型描述符:TPtrC和TPtr

 

  覺得沒什麼好講的,就是指針型,沒能擁有真的內存空間,末尾是C的是常量指針,不能修改指向的內容,但是可以修改指針的指向,而TPtr是沒有限制的,可以改變指向的內存地址的數據。

 

    基於棧緩存的描述符TBufC和TBuf    在上面的表中已有說明,相當於數組

   動態描述符:HBufC和RBuf     

    HBufCRBuf描述符類可用於在編譯期間大小不能確定的動態字符串數據(比如網絡接收數據),以及那些對棧內存來說過於龐大的數據。這些類被用於在C中需要使用malloc來分配數據的地方。

HBufC

HBufC8HBufC16(其對應的中立類 HBufCtypedef定義爲HBufC16)提供了一組靜態的NewL()函數,以便在堆上創建描述符。這些方法在沒有足夠內存可用的情況下會異常退出。所有的堆緩存必須使用這些方法來建立,或者也可以使用TdesC類的Alloc()AllocL()方法來建立,這兩個方法都可以從已存在的描述符中建立出HBufC的一個副本。一旦描述符以其所需的大小建立後,當它又需要更多空間時就不會自動重新分配大小,額外的內存需要使用ReAlloc() ReAllocL()方法來分配。

作爲一個類名中以C字符爲後綴的類,HBufC描述符不能被直接改變,但此類提供的賦值操作符允許替換緩存中的整個內容。要想在運行期間改變一個HBufC對象,應該首先從HBufC::Des()方法中獲得一個可變的描述符指針TPtr

_LIT(KTestBuffer, "Heap Based");

(這個是個內置類型,相當於#Define KTestBuffer “Heap Based“

// create a heap-based descriptor and place it on cleanup stack

HBufC* pHeap = HBufC::NewLC(32);

// create a pointer descriptor around pHeap

TPtr ptr(pHeap->Des());//把值賦給指針

// modify pHeap indirectly via ptr

ptr = KTestBuffer; //這裏有點費解,KTestBuffer難道也是指針?

...

// clean up

CleanupStack::PopAndDestroy(pHeap);

 

RBuf

RBuf類從TDes繼承而來,所以RBuf類的對象可以不用創建一個指向其數據的TPtr以修改其內容,這使得它要比HBufC更好用。在實例化時,RBuf對象既可以自己分配緩存,也可以取得先前分配好的內存或已有的堆描述符的控制權。爲了與本章開始時的Symbian OS命名習慣保持一致,RBuf類沒有被叫做HBufC,因爲與HBufC不同的是,RBuf不是直接在堆上創建的。RBuf描述符通常在棧上創建,並且擁有一個它需要負責清除的指向堆上資源的指針。

在內部,RBuf表現爲以下兩種方式之一:

●       TPtr直接指向內存中存儲的描述符數據類似,RBuf對象分配或取得描述符數據的擁有權。

●       作爲一個指向已存在堆描述符的指針——HBufC*RBuf對象取得HBufC的擁有權,並且擁有一個指向包含完整描述符對象的指針(完整是相對於前面所講的指向一個簡單數據塊的指針而言的)

然而這都是透明的,不需要去了解一個特定的RBuf對象在內部是怎麼描述的。使用此描述符類也相當直觀,就像使用其他的描述符類一樣,使用從TDesTDesC繼承而來的方法即可。

RBuf對於Symbian OS來說加入的時間相對較短,它最先出現在Symbian OS v8.1的文檔中,並且被廣泛應用於爲基於Symbian OS v9或其後版本的手機所設計的軟件中。

RBuf在許多最初的例子代碼中基本沒有用到,但是它卻是您在需要爲容納經常改變的數據而動態分配緩存時比起 HBufC來說更爲容易的類。

HBufC對於那些需要爲容納不會改變的數據而動態分配的描述符來說還是相當理想的;也就是說如果是不改變數據的訪問的話,它還是不錯的。

 

使用RBuf

RBuf對象可以通過Create()、CreateMax()或CreateL()方法來創建,並可以指定所能存儲的描述符數據的最大長度。也可以先實例化一個RBuf,然後將另一個描述符的內容複製進去,如下所示:

RBuf myRBuf;

LIT(KHelloRBuf, "Hello RBuf!"); // Literal descriptor

myRBuf.CreateL(KHelloRBuf());

CreateL()爲RBuf分配了一段緩存來引用。如果RBuf之前擁有一段緩存,由於CreateL()在分配新的緩存引用前不會將其清除,所以必須先調用Close()來釋放先前擁有的內存。

另一種方法是先實例化RBuf,然後再用Assign()方法取得一段已存在內存的所有權。

// Taking ownership of HBufC

HBufC* myHBufC = HBufC::NewL(20);

RBuf myRBuf;

myRBuf.Assign(myHBufC);

Assign()也會使RBuf已經擁有的數據孤立,所以在重新指定之前要調用Close()來避免內存泄漏。

在特定操作需要更多內存時,RBuf類不會去操縱緩存的大小或者爲它重新分配內存。如果一個可變的方法——比如Append()——在沒有足夠可用內存時被RBuf對象調用,那麼將會出現一個嚴重錯誤。作爲程序員,您應該爲保證RBuf對象在其緩存內有足夠空間而負責,並可以在需要時使用ReAllocL()方法:

// myRBuf is the buffer to be resized e.g. for an Append() operation

myRBuf.CleanupClosePushL(); // push onto cleanup stack for leave-safety

myRBuf.ReAllocL(newLength); // extend to newLength

CleanupStack::Pop(); // remove from cleanup stack

注意上面的例子用到了CleanupClosePushL(),來把RBuf類推入清除棧。清除工作在調用Close()(或者是調用CleanupStack::PopAndDestroy(),當RBuf是通過調用RBuf::
Cleanup-ClosePushL()被推入清除棧時)時開始,這對於其他R類來說很常見。

 

字面描述符

字面描述符與其他描述符類型略有不同。它們相當於C 中的static const char[]並且由於它們是常量,所以可以被構建在ROM裏以便在運行時節省內存。一組e32def.h中的宏可以用來定義Symbian OS的兩種不同類型的字面文字,_LIT和_L。

因爲更具效率,所以_LIT宏更適合用作Symbian OS的字面文字。它的典型用法如下:

_LIT(KSymbianOS, "Symbian OS");(注意 K開頭一般都是常量)

_LIT宏在程序的二進制代碼中構建了一個名爲KSymbianOS的TLitC16類型的對象,存儲了相應的字符串(本例中是“Symbian OS”)。顯式的宏定義_LIT8和_LIT16行爲相似,不過_LIT8構建的是TLitC8類型的窄字符串。

TLitC8和TLitC16不是從TDesC8和TDesC16繼承而來的,但是它們擁有和TBufC8及TBufC16相同的二進制佈局。這就保證了所有可以傳入TDesC的地方也可以使用這些類型的對象。

Symbian OS還定義了表示空字符串的字面文字。有三種不同的null描述符,定義如下:

// Build independent:

_LIT(KNULLDesC,"");

// 8-bit for narrow strings:

_LIT8(KNULLDesC8,"");

// 16-bit for Unicode strings:

_LIT16(KNULLDesC16,"");

雖然在測試代碼中(其對內存的使用稍微寬鬆些)還有可能用到_L宏,但是在產品代碼中已經不推薦使用它了。它可以在如下所示的一行代碼裏定義並使用:

TBuf<10> KSymbianBuf(_L("Symbian OS"));

 

如有錯誤 請斧正 諒解  博文完

 

                                                                                                                           寶傑    文

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