版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、諾基亞symbian 手冊匯編Symbian OS Basics Basic Types 在Symbian中,很多C+基本類型都被重新定義了,最好使用Symbian的,理由如下:· 所有Symbian API都是用的Symbianc重定義的 · 將來Symbian OS由32位轉(zhuǎn)為64位時(shí),支持性更好 · 這本身就是Symbian C+ Coding Standards所要求的Integers typedef signed int TInt; C+中的signed int,32位,基本用法類似。
2、 typedef unsigned int TUint; 一般用于計(jì)數(shù)器(Counter)或者標(biāo)記(Flags)。其他Int類型:TInt64, TInt32, TInt16,TInt8; 同時(shí)有一份TUint的版本。Text text類型在Symbian編程中基本不用,而一般采用描述符(descriptor)。TText默認(rèn)是16位的。Boolean typedef int TBool; 有兩個(gè)枚舉值:ETrue和EFalse。TBool變量最好不要直接和ETure和EFalse比較。如下:TBo
3、ol flag = ETrue;if (flag) / if (!flag) flag = EFalse; Floating Point 對浮點(diǎn)數(shù)的支持視處理器而定,如果沒有FPU,效率非常低,所以最好是不要用浮點(diǎn)數(shù)。 如果一定要用,盡量轉(zhuǎn)化為整數(shù)操作。typedef float TReal32; typedef double TReal64; typedef double TReal;TAny typedef void TAny;TAny一般只用作指針,其他情況下用v
4、oid比較好。TAny* MyFunction(); void MyOtherFn();TAny* 在很多Symbian API中都用到了,如:static TUint8* Copy( TAny* aTrg, const TAny* aSrc, TInt aLength);Enumerations enum TState EOff, Eon, EInit;Enumeration類型應(yīng)該以T開頭,而枚舉值應(yīng)該以E開頭。 TState state = GetState();if (state = EOn)
5、;/Do something here Coding Conventions T類:只包含值,而不包含指針以及外部的資源,在棧上分配空間。TVersion osVersion = User:Version(); C類:所有需要分配內(nèi)存的類都必須從CBase繼承并且以C開頭。class CExample : public CBaseprivate: CDesCArrayFlat* iArray; CExample* example = new (ELeave) CExample; &
6、#160; R類:包含指向某個(gè)資源的handler。RTimer timer;timer.CreateLocal(); M類:定義一個(gè)接口,一般只包含純虛函數(shù),不包含成員數(shù)據(jù),減少類之間的依賴,用來接受回調(diào)消息。class MEikStatusPaneObserver public: virtual void HandleStatusPaneSizeChange() = 0;任何實(shí)現(xiàn)MEikStatusPaneObserver接口的類都必須實(shí)現(xiàn)HandleStatusPa
7、neSizeChange()函數(shù)。Variable Naming Conventions · 成員變量以“i”開頭 · 參數(shù)以“a”開頭 · 動態(tài)變量隨便,以小寫字母開頭 · 常量以“K”開頭 · 盡量不要使用全局變量,不能使用全局靜態(tài)變量。Functions · 函數(shù)以大寫字母開頭,如AddFileNameL(); · 以D結(jié)尾表
8、示deletion of an object · 以L結(jié)尾表示函數(shù)可能leave · 以C結(jié)尾表示一個(gè)item被放到cleanup stackCasting Casting用于在類(classes)和類型(types)之間作轉(zhuǎn)化,Symbian中仍然可以使用C中語法。 dynamic_cast:不支持,Symbian中沒有RTTI。 static_cast:把一個(gè)基類轉(zhuǎn)化為一個(gè)繼承類。 TInt intValue = 0xff;TUint8
9、byteValue = static_cast<TUint8>(intValue); reinterpret_cast:把一個(gè)指針類型轉(zhuǎn)化為另外一個(gè)指針類型,如integer轉(zhuǎn)化為point類型或者相反。TUint32 fourBytes = 0;TUint8* bytePtr = reinterpret_cast<TUint8*> (&fourBytes);bytePtr+;*bytePtr = 0xFF; const_cast:移除一個(gè)類的const屬性。內(nèi)存管理Why Memory Managemen
10、t Symbian OS本身就是為內(nèi)存和資源受限的設(shè)備開發(fā)的,應(yīng)用程序運(yùn)行過程中很可能碰到內(nèi)存用光,或者硬件資源不可用的情況。而這種exceptions是通過修改程序無法解決的,所以遵守以下幾條:盡量不要使用不必要的RAM盡早釋放資源,如文件server等當(dāng)你每次申請內(nèi)存時(shí),都須準(zhǔn)備處理out-of-memory錯(cuò)誤當(dāng) out-of-memory錯(cuò)誤發(fā)生時(shí),返回到一個(gè)stable的狀態(tài),并釋放所有期間申請到的資源Stack and Heap Stack:默認(rèn)大小8kb,自動刪除,如 TInt i = 0; Heap
11、:至少.5Mb,由程序員手動刪除,如 CMyObj* obj = new (ELeave) CMyObj;Leaves 首先介紹Conventional C+ Memory Management,在Symbian看來,這是非常低效率的。NULL Pointer Checking if (myObj = new CMyObj( ) ) = NULL) /Error Handling ANSI C+ Exeption Handling try /throw an Exception catch (int e) /Error H
12、andling 在Symbian中推薦采用Leave,如果內(nèi)存或者資源不能分配到,這個(gè)代碼就會Leave,沿著Call Stack,直到操作系統(tǒng)或者在某個(gè)函數(shù)中被Handle掉。 所有可能Leave的函數(shù)最好以L結(jié)尾,保證該函數(shù)的用戶知道這個(gè)函數(shù)可能Leave。 Leave的例子:動態(tài)內(nèi)存分配: return new (ELeave) TUint81000;產(chǎn)生一個(gè)Leave:User:Leave(KErrNotFound);內(nèi)存不足時(shí)Leave:User:LeaveNoMemory();NULL的時(shí)候Leave:
13、User:LeaveIfNull(aNotify);當(dāng)發(fā)生錯(cuò)誤時(shí)Leave:RFs fs; TInt err = fs.Connect(); User:LeaveIfError(err); 處理Leave: 操作系統(tǒng)有默認(rèn)的處理Leave的方式:在程序啟動過程中:直接關(guān)閉應(yīng)用程序。應(yīng)用程序啟動后:顯示一個(gè)錯(cuò)誤消息。 開發(fā)者可以通過trap裝置來處理Leave。TRAP(_r, _s)和TRAPD(_r, _s),其中:_r:是一個(gè)TInt類型的leave code,默認(rèn)值為TErrNone。_s:一系列可能Leav
14、e的C+ Statements。 TRAPD(err, DoFunctionL(); if (err != KErrNone) /Error Handling else /Everything is well &
15、#160;The Cleanup Stack cleanup stack用于存儲在leave發(fā)生后需要deallocating的局部變量(指針)。即:當(dāng)一個(gè)函數(shù)leave了,所有在cleanup stack上的對象會被全部刪除掉。 Cleanup Stack的使用方法:CleanupStack:PushL(ptr) :當(dāng)發(fā)生leave時(shí)所有內(nèi)存都會被釋放CleanupClosePushL(handle):當(dāng)發(fā)生leave時(shí)這個(gè)句柄(handler)會被關(guān)閉CleanupStack:Pop(pointer):第一個(gè)元素出棧CleanupStac
16、k:PopAndDestroy(pointer):第一個(gè)元素出棧并釋放內(nèi)存 如果一個(gè)函數(shù)可能leave,檢查一下兩種情況:如果leave了,是否所有在堆(heap)上的元素都在cleanup stack中了如果沒有l(wèi)eave,你是否自己恰當(dāng)?shù)貙⑺鹀leanup了CMyClass* CMyClass:NewL(TInt aBufSize) CMyClass* self = new (ELeave) CMyClass; CleanupStack:PushL(self); self->Constr
17、uctL(aBufSize); CleanupStack:Pop(self); return self; 如果某個(gè)函數(shù)會在cleanup stack上留下一個(gè)對象,那么他必須以C結(jié)尾。Two Phase Construction C+構(gòu)造函數(shù)一定不能leave。所有內(nèi)存和資源的分配應(yīng)該在第二階段構(gòu)造函數(shù)ConstructL( )中完成。編碼指南,所有用戶定義的C類必須:定義NewL和NewLC函數(shù)為public static定義ConstructL和C+ Constructor為privateB
18、est Practise Construction的規(guī)則:默認(rèn)的C+構(gòu)造函數(shù)中不能含有可能leave的代碼可能發(fā)生leave的函數(shù)必須在ConstructL中被調(diào)用如果基類也有ConstructL,必須首先調(diào)用,不要忘了explicit scoping Destruction的規(guī)則:C類必須在析構(gòu)函數(shù)中刪除它自己所包含的對象在刪除一個(gè)對象后,把它的指針設(shè)為NULL不要刪除不是本類所擁有的對象在reallocation前首先刪除對象,并且將其指針設(shè)為NULL Further Discussion:
19、Preserve Stack Memory:每個(gè)進(jìn)程只有8K,以引用的方式傳遞參數(shù),大的對象放在堆上Preallocation vs last moment allocation:一般的原則是只在使用前分配資源并且在使用后馬上釋放。但是 preallocation的好處是節(jié)約處理時(shí)間,并且在沒有內(nèi)存的情況下照常運(yùn)行(資源已經(jīng)分配到了)where to put trap harness:最基本的情況是依靠GUI應(yīng)用程序
20、的框架。根據(jù)應(yīng)用的不同,可以自定義粒度。Error Code Returns vs. leaving functions:在執(zhí)行某個(gè)處理前檢測是否會出現(xiàn)問題,如下代碼: User:LeaveIfError(fs.Connect(); Memory Leaks 如果
21、你的程序有內(nèi)存泄露,在模擬器上關(guān)閉時(shí)會crash。盡早發(fā)現(xiàn)并解決你的內(nèi)存泄露,因?yàn)槟憧梢宰凡榈侥憧赡軐?dǎo)致內(nèi)存泄露的代碼改動。如果實(shí)在找不到,可用下面方法: Heap Balance Checking:_UHEAP_MARK_UHEAP_MARKEND 用上述這兩個(gè)宏放在你要檢查的代碼的開頭和結(jié)尾,如果發(fā)生panic,則說明這段代碼中發(fā)生了內(nèi)存泄露??梢郧短资褂?。 Panics Panic是一個(gè)未經(jīng)處理的exception,暗示著一個(gè)無法解決的錯(cuò)誤。一般程序有以下三類錯(cuò)誤:程序錯(cuò)誤:如引用一個(gè)超過數(shù)組范圍的元素環(huán)境錯(cuò)
22、誤:內(nèi)存、磁盤空間不夠,或缺少其他資源等用戶錯(cuò)誤:輸入錯(cuò)誤數(shù)據(jù) 可以使用trap和cleanup stack技術(shù)來解決環(huán)境和用戶錯(cuò)誤,但是對于第一類的程序錯(cuò)誤,我們無法恢復(fù),最好是使用User:Panic()函數(shù),它帶有兩個(gè)參數(shù),第一個(gè)是string,第二個(gè)是Tint。描述符Introduction 描述符(Descriptors)封裝了字符串和二進(jìn)制數(shù)據(jù),用于替代C中的以NULL結(jié)尾的字符串。它的長度和數(shù)據(jù)都封裝在了描述符中,Symbian API中用的都是描述符。如: TPtrC ptr (KHelloWorld
23、); CEikonEnv:Static()->InfoMsg(ptr);Main Types of Descriptors 主要可以分為以下幾類,其中帶C的是不可修改的。 · Abstract:(TDes、TDesC),其他描述符的基類,不能實(shí)例化,一般用作函數(shù)的參數(shù)。 · Literal:(TLitC,_LIT()),用于存儲literal string,一般使用后者。 · Buffer:(TBuf,TBufC),數(shù)據(jù)存儲于棧上,大小在編譯時(shí)確定。 · Heap:(HBufC),數(shù)據(jù)存儲于堆上,
24、大小在運(yùn)行時(shí)確定。 · Pointer:(TPtr,TPtrC),引用存儲于類之外的數(shù)據(jù)Descriptor Modification 描述符可以是可修改的和不可修改的,通常帶C的都是不可修改的,不可修改的是可修改的基類。 · Moidfiable:提供了訪問和修改數(shù)據(jù)的API,如TBuf · Non-Modifiable:數(shù)據(jù)只可以被訪問,不可修改。但是通過Des()函數(shù)可返回一個(gè)可修改的指針Descriptor Width 在描述符類后加上8或者16影響了存儲在描述符中的數(shù)據(jù)的寬度,默
25、認(rèn)是16位的,處理二進(jìn)制或ASCII時(shí)采用8位。· 8位:(TDesC8),用于二進(jìn)制數(shù)據(jù)或者ASCII字符串 · 16位:(TDesC16),默認(rèn),Unicode下面開始對上述5類描述符進(jìn)行詳細(xì)介紹,首先看一下類繼承關(guān)系
26、60; 這里顯示的是8位的,16位默認(rèn)的類繼承關(guān)系與此一致Abstract Descriptors 除Literal外的所有描述符的基類,提供了基本的接口和基礎(chǔ)功能。他們本身不能實(shí)例化,一般用作函數(shù)參數(shù)。TDesC:提供了比較、復(fù)制、搜索、提取部分字符串的函數(shù)。TInt TDesCUtil:SumLengths(const TDesc& aDesC1, const TDesc& aDesC2) return aDesC1.Length() + aDesC2.Length(); TDes:繼承自TDesC,添
27、加了許多用于修改數(shù)據(jù)的函數(shù)。其最大長度是描述符被創(chuàng)建時(shí)確定的。TInt TDesCUtil:AppendL(TDesc& aTarget, const TDesc& aDesC) TInt sumLen = aTarget.Length() + aDesC.Length(); if (aTarget.MaxLength() < sumLen) User:Leave(KErrOverflow); aTa
28、rget.AppendL(aDesC); Literal Descriptors 提供了一種將字符串放在只讀存儲空間中的機(jī)制(實(shí)際存放在程序的數(shù)據(jù)區(qū),而不是真的在ROM中)。一般不采用TLitC而直接采用_LIT()宏。 _LIT(KHelloWorld, "Hello World!"); 通過()操作符可以得到 const TDesC&。 TInt length = KHelloWorld().Length(); 在函數(shù)參數(shù)為const TDesC&可以
29、直接使用KHelloWorld。iLabel->SetTextL(KHelloWorld);Buffer Descriptors 將數(shù)據(jù)作為本身的一部分存儲在stack上,他們的最大長度是在編譯時(shí)確定的。 TBuf<16> helloWorld = KHelloWorld;TInt len = KHelloWorld().Length();helloWorldlen-1='?' 在內(nèi)存中如下所示: TBufC的用法如下:_LIT(KHelloWorld, "Hello World");cons
30、t TInt maxBuf = 32;TBufC<maxBuf> buf;TInt currentLen = buf.Length(); / = 0buf = KHelloWorld;currentLen = buf.Length(); / = 11TText ch = buf2; / = 'l'TBuf的用法如下:const TInt bufLen = 6;TUInt8 objType = 1;TUInt8 objId = 1;TUInt8 xCoord = 128;TUInt8 yCoord = 192;.TBuf8<bufLen> buf; buf
31、.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 用于引用存儲在其他地方的數(shù)據(jù),如:const unsigned char KBuffer = 0x00, 0x33, 0x66, 0x99, 0xbb, 0xff;TPtrC8 bufferPtr( KBuffer, sizeof(KBuffer);iSocket.Wr
32、ite(bufferPtr, iStatus);在內(nèi)存中如下所示:TPtr的用法:_LIT(KHelloWorld, "Hello World");const TInt maxBuf = 32;TBufC<maxBuf> buf;buf = KHelloWorld;TPtr ptr = buf.Des();ptr7 = 'a' ptr8 = 'l' ptr9 = 'e' ptr10 = 's' CEikonEnv
33、:Static()->InfoMsg(ptr); / "Hello Wales"Heap Descriptors 動態(tài)在堆(heap)上分配,通過HBufC的API,數(shù)據(jù)可以被set和reset,但是不能被修改。如:HBufC* heapBuf = HBufC:NewL(KHelloWorld().Length();*heapBuf = KHelloWorld();delete heapBuf; 在內(nèi)存中的情況如下圖所示: HBufC通常在以下幾
34、種情況下使用: · 在運(yùn)行時(shí)從資源文件中加載字符串 · 從用戶界面中接收用戶輸入的字符串 · 從應(yīng)用程序引擎中接收字符串,如contacts database中的名字 對HBufC中的內(nèi)容進(jìn)行修改:_LIT(KHello, "Hello!");_LIT(KWorld, "World!"); HBufC* heapBuf = HBufC:NewL(KHello().Length();*heapBuf = KHello; /buf holds "
35、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.ptrKHello().Length() - 1 = ' 'ptr += KWorld;iTopLabel -> S
36、etTextL(ptr);CleanupStack:PopAndDestroy();DrawNow();下面介紹Descriptors的具體用法: Non-Modifying Methods Length(),Size(),Left(),Right(),Mid(),Compare(),Locate(),LocateReverse(),F(xiàn)ind(),Match()等。以下代碼示例描述了如何在一個(gè)descriptor中找到<>中的內(nèi)容,如果不存在,返回整個(gè)字符串:static const TUint KAddressStartChar =
37、 '<' static const TUint KAddressEndChar = '>'TPtrC ExtractAddressNumber( const TDesC& aAddressString) TInt addrStart = aAddressString.Locate(KAddressStartChar ) + 1; TInt addrEnd = aAddressString.LocateReverse(KAddressEndChar ) ; &
38、#160; if (addrStart = KErrNotFound) | (addrEnd = KErrNotFound) | (addrStart >= addrEnd) ) addrStart = 0; addEnd = aAddressString.Length(); return (aAddressString.Mid(add
39、rStart, (addrEnd - addrStart) ) ); Modifying Methods Zero(),Copy(),Num(),F(xiàn)ormat(),Insert(),Replace(),Delete(),Append(),Trim()等。代碼示例:_LIT(KText, "Hello World!");_LIT(KNewText, "New Text");_LIT(KReplaced, "Replaced");TBuf<16> buf1(KText); buf
40、1.Delete(6, 6); / length is now 6, leaving "Hello" in the bufferTBuf<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
41、 in Method Declarations · 在函數(shù)參數(shù)中盡量使用基類 · 使用中性的描述符,一般情況下使用TDesC而不是TDesC8或者TDesC16 · 當(dāng)描述符內(nèi)容不應(yīng)該改變時(shí),使用const修飾符 · 經(jīng)典用法:void SetText(const TDesC& aText); TPtrC Text() const; Character Conversions CCnvCharacterSetConverte
42、r類提供了在Unicode和其他字符集編碼之間轉(zhuǎn)換的方法。ASCII本來就是Unicode的一個(gè)子集,無須使用該類。和Unicode之間的轉(zhuǎn)換方法如下所示:TBuf16<64> UnicodeBuf;_LIT8(KAsciiStr, "Hello");UnicodeBuf.Copy(KAsciiStr); Unicode和拉丁語系之間的轉(zhuǎn)化可使用如下的代碼:TBuf8<64> Latin1Buf;_LIT16(KUnicodeStr1, "hello");_LIT16(KUnicodeStr2, "
43、I have got 10x20AC."); /x20AC is a euroLatin1Buf.Copy(KUnicodeStr1); /OKLatin1Buf.Copy(KUnicdoeStr2); /Not as you wanted.Symbian操作系統(tǒng)將應(yīng)用程序設(shè)計(jì)為單線程的,在大多數(shù)情況下等待異步事件的產(chǎn)生和完成。雖然可以使用多線程,但是不提倡這種做法,一方面是上下文切換開銷導(dǎo)致電池使用壽命降低,另外一方面就是開發(fā)較復(fù)雜。 Symbian使用Active Object框架來處理操作系統(tǒng)的異步事件處理特性。由兩方面構(gòu)成:
44、183; The Active Scheduler: 用來調(diào)度事件,每個(gè)線程只能有一個(gè) · Active Objects:這些對象用于處理事件,在一個(gè)線程中可以有多個(gè)Asynchoronous Functions Symbian OS中包含很多異步函數(shù),任何含有TRequestStatus&參數(shù)的函數(shù)都是異步的。如:void After (TRequestStatus& aStatus, TTimeIntervalMicroSeconds32 aInterval)· TRequestStatus:包含一個(gè)TIn
45、t類型的狀態(tài)值,調(diào)用時(shí)值為TRequestStatus · 時(shí)間請求當(dāng)且僅當(dāng)aStatus != TRequestStatus時(shí)完成,而非函數(shù)返回時(shí)完成Synchoronous Functions 先看如下例子:創(chuàng)建一個(gè)Timer,并且請求一個(gè)10秒的timeout。RTimer timer;timer.CreateLocal();TRequestStatus status;timer.After(status, 10000000);User:WaitForRequest(status); 這是同步調(diào)用,即當(dāng)User:WaitFor
46、Request(status);執(zhí)行時(shí),其他事件都被掛起,用戶界面停止響應(yīng)。一個(gè)比較好的解決辦法是:當(dāng)時(shí)間請求結(jié)束后收到一個(gè)通知,而在該過程中其他事件可以被處理。Active Objects 可以被用來處理異步函數(shù)調(diào)用。從CActive繼承,并有如下成員變量:優(yōu)先級決定了何時(shí)被檢查是否完成· TRequestStatus:類成員變量,iStatus,傳入異步函數(shù)調(diào)用 · RunL():當(dāng)異步請求結(jié)束時(shí)被調(diào)用 · DoCancel():當(dāng)異步請求被取消時(shí)調(diào)用Active Scheduler
47、 當(dāng)應(yīng)用程序啟動時(shí),都包含一個(gè)系統(tǒng)創(chuàng)建的默認(rèn)Active Scheduler。在主線程中進(jìn)行事件循環(huán),完成以下功能;· 同步等待任何發(fā)出請求的結(jié)束 · 根據(jù)優(yōu)先級測試每個(gè)注冊的active object,看是否有發(fā)出的請求、它的請求是否已經(jīng)結(jié)束 · 對于每個(gè)請求已經(jīng)完成的active object,調(diào)用其RunL()函數(shù) · 在RunL()返回后,再檢查其他請求 · 對于RunL()可能Leave的情況,調(diào)用需函數(shù)RunError() 通過 static void Add ( CActive* aActive)函數(shù)將一
48、個(gè)active object注冊到active scheduler中。 Implementing Active Objects 要實(shí)現(xiàn)一個(gè)Active Object,必須遵循以下步驟:· 從CActive繼承 · C+構(gòu)造函數(shù)中:設(shè)置優(yōu)先級EPriorityStandard,調(diào)用CActiveScheduler:Add() · 提供一個(gè)進(jìn)行異步函數(shù)調(diào)用的成員函數(shù),傳入:CActive:iStatus,調(diào)用CActive:SetActive() · 實(shí)現(xiàn)RunL()和DoCancel()函數(shù),因?yàn)樗麄兌际羌兲摵瘮?shù),必須實(shí)現(xiàn)
49、83; 在析構(gòu)函數(shù)中調(diào)用CActive:Cancel() Symbian中的CPeriodic類已經(jīng)是一個(gè)對timer封裝的active object了。 上圖展示了Active Object使用的調(diào)用流程。Active Objects Other uses· 處理異步函數(shù)調(diào)用 · 將處理器開銷大的任務(wù)分成幾個(gè)階段 · 實(shí)現(xiàn)一個(gè)異步服務(wù) · 調(diào)用一系列的異步函數(shù)客戶端/服務(wù)器框架本課從用戶角度學(xué)習(xí)客戶端/服務(wù)器框架,關(guān)注如何使用客戶端API而非實(shí)現(xiàn)服務(wù)器端功能。Introduction
50、160; Symbian OS使用客戶端/服務(wù)器框架來訪問系統(tǒng)資源:如打開文件、撥打、設(shè)置鬧鐘等。需要由服務(wù)器來管理系統(tǒng)資源來防止多個(gè)客戶訪問可能引起的問題。 服務(wù)器運(yùn)行在自己的進(jìn)程或者線程空間中,任何來自客戶端的請求都要穿過線程邊界。這表明:服務(wù)器對資源有著絕對的控制權(quán),可以拒絕來自客戶端的請求(如一個(gè)客戶端請求刪除另外一個(gè)客戶端正在編輯的文件)。 Example Servers and Client APIs Symbian OS主要包含的服務(wù)器,如下圖所示,其中:· 藍(lán)色:在自己的進(jìn)程空間中 · 綠色:在一個(gè)線程空間
51、中,與其他服務(wù)器共享一個(gè)進(jìn)程 在每個(gè)Server中列出的類描述了客戶端可以使用的API,以下是每個(gè)服務(wù)的概述:Kernel Server:運(yùn)行在最高權(quán)限,管理系統(tǒng)中所有其他進(jìn)程對硬件和內(nèi)存的訪問。· RTimer:提供異步時(shí)間服務(wù) · RThread: 提供線程訪問和創(chuàng)建 · RSemaphre:提供線程間同步機(jī)制File Server:提供了對文件系統(tǒng)的訪問· RFs:提供到文件服務(wù)器的一個(gè)會話,可以完成高層次的驅(qū)動器、目錄和文件的操作以及獲取目錄列表 · RFile:提供文件創(chuàng)建、讀取和寫入操
52、作 · RDir:讀取目錄中所含的entriesWindow Server:應(yīng)用程序框架使用窗口服務(wù)器來處理按鍵事件以及進(jìn)行屏幕顯示操作· RWindow:提供屏幕顯示操作,開發(fā)人員一般使用CCoeControl:raw() · RAnim:與服務(wù)器端animation通信(服務(wù)器端高優(yōu)先級drawing) · CWindowGc:提供屏幕繪圖操作的圖形上下文Font and Bitmap Server:在客戶端之間共享字體和位圖· RFbsSession:負(fù)責(zé)與字體和位圖服務(wù)器之間的一個(gè)會話,程序開發(fā)中一般不使用該類 · CFbsB
53、itmap:表示一個(gè)位圖 · CFbsDevice:表示一個(gè)用于顯示位圖的圖形設(shè)備Telephony Server:負(fù)責(zé)設(shè)備的功能· RTelServer:提供到服務(wù)器的工具級別的訪問 · RPhone:提供設(shè)備上操作 · RLine:提供一路的操作 · RCall:提供在某一路上撥打/接收的功能Socket Server:提供通過多種媒體創(chuàng)建一個(gè)TCP/IP或者UDP的socket· RSocketServ:連接到Socket服務(wù)器,發(fā)現(xiàn)所有的協(xié)議 · RSocket:提供連接到,接收和發(fā)送數(shù)據(jù)到另外一個(gè)socket的功能
54、 · RHostResolver:提供DNS解析功能Comms Server:允許開發(fā)者通過電纜或者紅外使用串行口· RCommServ:提供一個(gè)到Comms Server的會話 · RComm:提供通過串行口通行的功能Message Server:保存消息數(shù)據(jù)并且提供到消息功能如SMS,MMS,OBEX和Mail的訪問· CMsvSession:描述一個(gè)和消息服務(wù)器的會話 · CMsvEntry:描述消息stroe中的一個(gè)entry · CBaseMtm:提供訪問和操作消息服務(wù)器entry的接口Server Plug-ins
55、0; 客戶端/服務(wù)器架構(gòu)具有很好的可擴(kuò)展性,許多服務(wù)器都允許添加plug-in模塊,為新的技術(shù)、協(xié)議和媒質(zhì)提供功能。所添加的新功能可以通過一個(gè)generic api進(jìn)行訪問。如:· Message Server:MMS,SMS,POP3,SMTP · Socket Server:紅外,藍(lán)牙,CSD(Circuit Switched Data)Sessions 下圖展示了不同的客戶端/服務(wù)器會話場景:Client1:和服務(wù)器之間只有一個(gè)會話,在應(yīng)用程序的control environment中與文件服務(wù)器的默認(rèn)會話。Client2:和
56、服務(wù)器之間有兩個(gè)會話,除默認(rèn)會話外還有一個(gè)顯式的文件操作。Client3:和服務(wù)器之間有一個(gè)會話和兩個(gè)字會話,與文件服務(wù)器有一個(gè)連接,對每個(gè)打開的文件分別由一個(gè)會話。 Requests 下圖展示了一個(gè)客戶端如何穿越線程邊界與服務(wù)器進(jìn)行通信,RSessionBase等類都是基類,需要繼承。具體過程如下:· 調(diào)用一個(gè)客戶端接口所提供的API,如RFs:rive(),來獲取驅(qū)動器信息 · RSessionBase:SendReceive()被調(diào)用,參數(shù)為操作碼和一個(gè)包含4個(gè)指向客戶端內(nèi)存指針的數(shù)組 · 內(nèi)部的private函數(shù)RSessionB
57、ase:SendSync()被調(diào)用,訪問內(nèi)核 · 內(nèi)核調(diào)用服務(wù)器線程中的CSession2:ServiceL(), 封裝了消息內(nèi)容的RMessage2作為參數(shù) · 調(diào)用RMessage2:WriteL()在用戶端的空間中寫入所需要的數(shù)據(jù) · 調(diào)用RMessage2:Complete()來表示對客戶端請求的完成Using Client APIs 客戶端API繼承自RSessionBase或者RSubSessionBase,必須以以下順序使用:· 建立到相應(yīng)的服務(wù)器的連接,一般通過函數(shù)Connect()或者Open()。 ·
58、; 在建立連接后,可以使用所有的API,請求可以通過同步或者異步的方式發(fā)送。 · 在使用完后必須關(guān)閉到服務(wù)器的連接,否則將發(fā)生資源泄漏 需要注意的是:可能會發(fā)生leave,資源必須使用CleanupClosePushL()放到cleanup stack上。 ClientAPI的使用案例:HBufC* CFileUtil:ReadL(const TDesC& aFileName) RFs fs; User:eaveIfError(fs.Connect();
59、;CleanupClosePushL(fs); RFile file; User:eaveIfError(file.Open(fs, aFileName, EFileRead); CleanupClosePushL(file); TInt fileSize; file.Size(fileSize); HBufC8* data = HBufC8:NewL(fileSize); file.Read(data);
60、0;CleanupStack:opAndDestroy(2); return data;資源文件資源文件 · 指定了應(yīng)用程序的相關(guān)信息,包含要顯示的控件定義(如菜單,對話框等),是所有應(yīng)用程序所必須的。 · 資源文件的后綴名為<application name>.rss。最多可以包含4095個(gè)資源。 · 一個(gè)應(yīng)用程序可以包含多個(gè)資源文件,并在運(yùn)行時(shí)動態(tài)加載其他資源文件。 · Uikon預(yù)先定義了許多在資源文件中可以使用的結(jié)構(gòu)體。 · 資源文件需要編譯成二進(jìn)制文件,在C+代碼中需要include編譯產(chǎn)生的.rs
61、g文件。具體的文件及解釋如下: / 4 letter ID 該字段必須每個(gè)應(yīng)用程序唯一NAME S60R / INCLUDES 包含已經(jīng)定義的資源結(jié)構(gòu)#include <eikon.rh>#include <avkon.rh>#include <avkon.rsg>#include <appinfo.rh>/hrh用于包含枚舉常量,如菜單項(xiàng);rls定義了在UI中使用的字符串#include "S60ResourceLab.hrh"#include "
62、;S60ResourceLab.rls"/允許應(yīng)用程序指定版本號,可選RESOURCE RSS_SIGNATURE /為該應(yīng)用程序的默認(rèn)文件指定一個(gè)名字RESOURCE TBUF r_default_document_name buf="HEWB" /指定了所要顯示的菜單和soft keysRESOURCE EIK_APP_INFO menubar=r_s60resourcela
63、b_menubar; cba=R_AVKON_SOFTKEYS_OPTIONS_BACK; 菜單相關(guān):/定義了需要顯示的menu pane,txt字段為空(S80中才有位置顯示菜單的title,S60沒有)RESOURCE MENU_BAR r_s60resourcelab_menubar titles= MENU_TITLE menu_pa
64、ne=r_s60resourcelab_menu; txt="" /menu pane定義了一系列menu items,command就是HandleCommandL中接收的命令參數(shù),txt顯示給用戶。RESOURCE MENU_PANE r_s60resourcelab_menu items=
65、; MENU_ITEM command=EAknCmdExit; txt="Exit" , MENU_ITEM command=ES60ResourceLabCmdAppTest; txt="Test" 字符串相關(guān):字符串的內(nèi)容真正定義的位置是在本地化文件中,見后。RESOURCE TBUF r_s60resourcelab_text_goodbye
66、0; buf = qtn_s60resourcelab_text_goodbye; RESOURCE TBUF r_s60resourcelab_text_everyone buf = qtn_s60resourcelab_text_everyone; Localisation Files 每種顯示給用于的語言都有一個(gè)本地化文件,在該文件中包含所有需要翻譯的語言??梢栽趓ss文件中被條件包含,如下所示:#ifdef LAN
67、GUAGE_01 #include "HelloWorld01.rls"#elif defined LANGUAGE_02 #include "HelloWorld02.rls"#endif 示例:keyword symbolic_identifier the_stringrls_string qtn_caption_string "S60 Resource Lab"rls_string qtn_s60resourcelab_text_goodbye "Goodbye"Resource Compilation 資源編譯器將rss文件編譯為rsc文件,中間產(chǎn)生一個(gè)rsg的頭文件。 C+代碼中使用resource需要包含rsg頭文件,使用方法如下:HBufC* textResource = StringLoader
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度物流倉儲托盤租賃及倉儲信息共享合同3篇
- 2024版設(shè)備采購與分期付款合同2篇
- 二零二五年度林業(yè)資源個(gè)人林權(quán)流轉(zhuǎn)合同3篇
- 二零二五年度國際銷售代理傭金結(jié)算合同樣本6篇
- 菌移植微生態(tài)醫(yī)學(xué)服務(wù)體系產(chǎn)業(yè)鏈?zhǔn)痉俄?xiàng)目可行性研究報(bào)告模板-立項(xiàng)拿地
- 2024版綠化托管合同范本
- 2024版輸氣管道頂管施工合同3篇
- 二零二五年度物流倉儲與分銷服務(wù)合同5篇
- 二零二五年度礦山跡地植被恢復(fù)合同2篇
- 二零二五年度禾青幼兒園教玩具采購與幼兒園教學(xué)資源整合合同3篇
- 《小學(xué)生錯(cuò)別字原因及對策研究(論文)》
- 公司組織架構(gòu)圖(可編輯模版)
- 北師大版七年級數(shù)學(xué)上冊教案(全冊完整版)教學(xué)設(shè)計(jì)含教學(xué)反思
- 智慧水庫平臺建設(shè)方案
- 浙江省公務(wù)員考試面試真題答案及解析精選
- 系統(tǒng)性紅斑狼瘡-第九版內(nèi)科學(xué)
- 全統(tǒng)定額工程量計(jì)算規(guī)則1994
- 糧食平房倉設(shè)計(jì)規(guī)范
- 《設(shè)計(jì)專業(yè)導(dǎo)論》教學(xué)大綱
- 雙語閱讀:友誼的顏色
- 通用個(gè)人全年工資表模板
評論
0/150
提交評論