• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            franksunny的個(gè)人技術(shù)空間
            獲得人生中的成功需要的專注與堅(jiān)持不懈多過(guò)天才與機(jī)會(huì)。 ——C.W. Wendte

            symbian官方推薦使用活動(dòng)服務(wù)對(duì)象(CActive)來(lái)代替多線程的使用,我想這個(gè)道理是很明了的,在手機(jī)這樣的小內(nèi)存設(shè)備里,運(yùn)行多線程的程序是非常耗資源的,為了節(jié)約資源,symbian提供了一個(gè)活動(dòng)服務(wù)對(duì)象的框架,允許把程序里并發(fā)執(zhí)行對(duì)象(其實(shí)不是并發(fā),不過(guò)宏觀上看來(lái)是)放在一個(gè)線程里面執(zhí)行,這些并發(fā)工作的對(duì)象就通過(guò)活動(dòng)規(guī)劃器(ActiveScheduler)來(lái)進(jìn)行管理.

            關(guān)于這兩個(gè)東西的介紹,網(wǎng)上有一大堆的文檔,我就不在這里廢話了,如何使用呢?這里我先舉一個(gè)簡(jiǎn)單的計(jì)數(shù)器的例子.我選擇寫(xiě)一個(gè)exe的程序,也就是說(shuō)程序是以E32Main為入口的.

            GLDEF_C TInt E32Main()

            {

                CTrapCleanup* cleanup=CTrapCleanup::New();

                TRAPD(error,callInstanceL());

                if (error != KErrNone)

                {

                    printf("get error %d\r\n", error);

                }

                delete cleanup;

                return 0;

            }

            以上的內(nèi)容是每一個(gè)exe文件都應(yīng)該做的,CTrapCleanup* cleanup=CTrapCleanup::New()建立一個(gè)清除堆棧,以便程序在異常退出的時(shí)候把清除堆棧里面的資源都釋放掉.當(dāng)然你也可以加上堆檢測(cè)宏(__UHEAP_MARK,__UHEAP_MARKEND,這里我就不多說(shuō)了。TRAPDsymbian里面經(jīng)常使用的宏,功能類似于try,第一個(gè)參數(shù)是讓定義一個(gè)錯(cuò)誤返回值變量的名字, 后面就是可能有異常的你寫(xiě)的函數(shù).當(dāng)這個(gè)函數(shù)異常時(shí),程序不會(huì)crash, 你可以得到異常的原因.可以參考nokia論壇上的一些關(guān)于這些使用的文檔.

            接下來(lái)是vcallInstanceL函數(shù),在這個(gè)函數(shù)里面我來(lái)建立ActiveScheduler.

            LOCAL_C void callInstanceL()

            {

                CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();

                CleanupStack::PushL(scheduler);

                CActiveScheduler::Install(scheduler);

                TRAPD(error,doInstanceL());

                if(error)

                {

                    printf("error code=%d\r\n",error);

                }

                else

                {

                    printf("OK!\r\n[press any key]");

                }

                CleanupStack::PopAndDestroy(scheduler);

            }

            這段程序很簡(jiǎn)單就是創(chuàng)建一個(gè)活動(dòng)規(guī)劃器,并壓入清除棧,然后安裝活動(dòng)規(guī)劃器,這樣就可以用了.再執(zhí)行真正的實(shí)例函數(shù),最后出棧銷毀。doinstance(該函數(shù)將在最后的代碼中給出,主要的功能就是調(diào)用我們自己寫(xiě)的活動(dòng)計(jì)數(shù)器)我們放到最后來(lái)寫(xiě),現(xiàn)在來(lái)構(gòu)造我們的活動(dòng)計(jì)數(shù)器對(duì)象。

            class TimeCount : public CActive

            {

            public :

                static TimeCount* NewLC(); // 構(gòu)造函數(shù)

                ~TimeCount();

                void StartL();             // 計(jì)數(shù)開(kāi)始

                void ConstructL();

                void RunL();             // 延時(shí)事件到達(dá)以后的處理函數(shù)

                void DoCancel();         // 取消請(qǐng)求提交

                void setDelayTime(int delayTime);

            private:

                TimeCount();

                RTimer iTimer;          // 定時(shí)器

                int iTimeCount;         // 計(jì)數(shù)器

                 int mTime;            // 計(jì)數(shù)間隔時(shí)間 單位秒

            };

             

            TimeCount::TimeCount():CActive(0)  // 這里可以設(shè)置活動(dòng)對(duì)象的優(yōu)先級(jí)

            {

                // 把自己加入活動(dòng)規(guī)劃器

                CActiveScheduler::Add(this);

            }

             

            TimeCount* TimeCount::NewLC()

            {

                TimeCount* result = new (ELeave) TimeCount();

                CleanupStack::PushL( result );

                result->ConstructL();

                return result;

            }

             

            void TimeCount::DoCancel(void)

            {

                iTimer.Cancel();

            }

             

            void TimeCount::setDelayTime(int mTime)

            {

                DelayTime = mTime;

            }

             

            TimeCount::~TimeCount()

            {

                Cancel();

                iTimer.Close();

            }

             

            void TimeCount::StartL()

            {

                // 設(shè)定定時(shí)器狀態(tài)為每隔mTime秒鐘狀態(tài)完成一次

                iTimer.After(iStatus, 10000 * 100 * mTime);

                // 提交異步請(qǐng)求

                SetActive();

            }

             

            void TimeCount::ConstructL()

            {

                // 初始化計(jì)數(shù)器和定時(shí)器

                iTimeCount = 0;

                User::LeaveIfError(iTimer.CreateLocal());

            }

             

            void TimeCount::RunL()

            {

                // 計(jì)數(shù)器+1以后繼續(xù)提交延時(shí)請(qǐng)求事件

                printf("The Count is ->>%d", iTimeCount++);

                StartL();

            }

            每一個(gè)活動(dòng)服務(wù)對(duì)象都有一個(gè)iStatus來(lái)標(biāo)識(shí)當(dāng)前對(duì)象的狀態(tài).在這里我們把iStatus設(shè)定為iTimer.After(iStatus, 10000 * 100 * mTime);也就是定時(shí)器定時(shí)mTime秒鐘以后iStatus發(fā)生改變,這個(gè)時(shí)候活動(dòng)規(guī)劃器會(huì)收到這個(gè)狀態(tài)的改變,從而調(diào)用相應(yīng)活動(dòng)對(duì)象的處理函數(shù),也就是RunL函數(shù).RunL函數(shù)里面進(jìn)行計(jì)數(shù)和輸出,然后調(diào)用startL重新設(shè)置定時(shí)器和對(duì)象狀態(tài),再提交給活動(dòng)規(guī)劃器。這樣mTime秒鐘以后活動(dòng)規(guī)劃器會(huì)再次調(diào)用RunL函數(shù).一直這樣重復(fù),這樣就達(dá)到了計(jì)數(shù)器的效果。

            最后我們來(lái)寫(xiě)doinstanceL函數(shù)

            LOCAL_C void doInstanceL()

            {

                TimeCount* timeCount = TimeCount::NewLC();

                // 每隔一秒鐘打印一次

                TimeCount->setDelayTime(1);

                TimeCount->StartL();

                CActiveScheduler::Start();

                CleanupStack::PopAndDestroy(1);

            }

            創(chuàng)建好對(duì)象以后,加上CActiveScheduler::Start()程序就開(kāi)始運(yùn)行了,這句話告訴活動(dòng)規(guī)劃器該等待對(duì)象的狀態(tài)的改變了(正常情況下,一旦CActiveScheduler::Start()之后,程序直到CActiveScheduler::Stop()才能終止運(yùn)行),在這里就是timeCountiStatus的改變.iStatus改變并調(diào)用了RunL以后,繼續(xù)等待iStstus的改變,這樣我們使用活動(dòng)對(duì)象的計(jì)數(shù)器就能夠通過(guò)消息驅(qū)動(dòng)運(yùn)行起來(lái)了.

            這里的CActiveScheduler只管理了一個(gè)CActive對(duì)象,就是timeCount,可以用類似的方法實(shí)現(xiàn)多個(gè)CActive,并且都加入CActiveScheduler,CActiveScheduler將會(huì)等待所有加入它的CActive的狀態(tài)的改變,其中有一個(gè)的狀態(tài)改變就會(huì)去執(zhí)行對(duì)應(yīng)的活動(dòng)對(duì)象的處理函數(shù),當(dāng)狀態(tài)同時(shí)發(fā)生的時(shí)候,會(huì)通過(guò)對(duì)象的優(yōu)先級(jí)來(lái)決定先調(diào)用誰(shuí)的RunL函數(shù).CActiveScheduler也是非搶占式的,當(dāng)一個(gè)RunL函數(shù)還沒(méi)有執(zhí)行完的時(shí)候,如果另一個(gè)CActive的狀態(tài)改變,會(huì)等待RunL執(zhí)行完以后再執(zhí)行另一個(gè)CActive的處理函數(shù)(正因?yàn)檫@一點(diǎn),所以通常RunL函數(shù)不能設(shè)計(jì)為長(zhǎng)函數(shù),否則會(huì)阻塞活動(dòng)對(duì)象)

             本文在網(wǎng)上根據(jù)網(wǎng)上用人提供的原本閱讀學(xué)習(xí)而成,可算是轉(zhuǎn)載類型的。

             

             

            posted @ 2008-10-11 21:03 frank.sunny 閱讀(2566) | 評(píng)論 (0)編輯 收藏

            Active Object (AO) 框架,是Symbian的基本工作部分。它是為了滿足多個(gè)任務(wù)同時(shí)執(zhí)行的要求。在 Windows/Unix 平臺(tái)上,我們可以不加思索的使用多線程來(lái)完成多任務(wù)。可是在嵌入式平臺(tái)上,系統(tǒng)的資源是有限的。比如CPU、內(nèi)存都比我們平時(shí)用的個(gè)人計(jì)算機(jī)要低。這就要求嵌入式系統(tǒng)能夠合理的使用系統(tǒng)資源。不能頻繁的切換線程或者進(jìn)程。

            Symbian為這種特別需求設(shè)計(jì)了Active Object (AO)框架。AO框架是運(yùn)行于一個(gè)線程內(nèi)部的調(diào)度框架。其基本思想就是把一個(gè)單線程分為多個(gè)時(shí)間片,來(lái)運(yùn)行不同的任務(wù)

            這和多線程有很大區(qū)別。多線程之間是可以被搶占的(由操作系統(tǒng)調(diào)度),但是AO框架中的各個(gè)任務(wù)是不可被搶占的,一個(gè)任務(wù)必須完成,才能開(kāi)始下一個(gè)任務(wù)

            下面是多線程和AO框架的簡(jiǎn)單比較:

            多線程                                       AO框架

            可以被搶占                                   不可被搶占

            上下文切換耗費(fèi)CPU時(shí)間                       沒(méi)有上下文切換

            由操作系統(tǒng)調(diào)度                               由線程自己的AO框架調(diào)度

            每個(gè)線程都有至少4K Stack.                    AO沒(méi)有單獨(dú)的Stack.

            操作系統(tǒng)還要分配額外的資源記錄線程            只是一個(gè)Active Object.

            Symbian系統(tǒng)本身使用了大量的AO框架來(lái)實(shí)現(xiàn)一些系統(tǒng)服務(wù)。這使得Symbian和其他嵌入式系統(tǒng)相比較,對(duì)系統(tǒng)資源的使用更加合理。

            AO框架包括CActiveScheduler CActive (Active Object)。一個(gè)線程的所有的Active Object對(duì)象都被安裝在該線程的CActiveScheduler對(duì)象內(nèi).CActiveScheduler對(duì)象監(jiān)控每個(gè)Active Object是否完成了當(dāng)前任務(wù),如果完成了,就調(diào)度下一個(gè)Active Object來(lái)執(zhí)行。CActiveScheduler根據(jù)優(yōu)先級(jí)來(lái)調(diào)度各個(gè)Active Object.

             

            關(guān)于CActiveScheduler的創(chuàng)建和安裝,CActive的創(chuàng)建和安裝,和CActive的任務(wù)處理,可以參看 SDK 文檔。理解起來(lái)不難。下面要說(shuō)一個(gè)比較容易忽略的地方。這對(duì)理解AO框架非常重要。

            創(chuàng)建調(diào)度器:

            CActiveScheduler * scheduler = new (ELeave) CActiveScheduler;

            CleanupStack::PushL(scheduler);

            CActiveScheduler::Install(scheduler);

             

            運(yùn)行調(diào)度器:

            CActiveScheduler::Start();

             

            停止調(diào)度器:

            CActiveScheduler::Stop();

             

            以上代碼都是運(yùn)行在一個(gè)線程中的,一般來(lái)講,一個(gè)EXE只有一個(gè)主線程.

            可是如果真的有2個(gè)線程呢?

            為什么在當(dāng)前線程下調(diào)用CActiveScheduler::Start(),CActiveScheduler::Stop()運(yùn)行/停止的就是當(dāng)前線程的調(diào)度器而不是另一個(gè)線程的調(diào)度器?

            每個(gè)線程都有自己的CActiveScheduler,那么這個(gè)CActiveScheduler類是怎么調(diào)用CActiveScheduler::Start(),CActiveScheduler::Stop()來(lái)運(yùn)行/停止當(dāng)前的調(diào)度器的呢?

            我們看到Start/Stop并沒(méi)有參數(shù).

            打開(kāi)CActiveScheduler的類定義:

            class CActiveScheduler : public CBase

                {

            public:

                IMPORT_C CActiveScheduler();

                IMPORT_C ~CActiveScheduler();

                IMPORT_C static void Install(CActiveScheduler* aScheduler);

                IMPORT_C static CActiveScheduler* Current();

                IMPORT_C static void Add(CActive* anActive);

                IMPORT_C static void Start();

                IMPORT_C static void Stop();

                IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);

                IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);

                IMPORT_C virtual void WaitForAnyRequest();

                IMPORT_C virtual void Error(TInt anError) const;

            private:

                void DoStart();

                void OwnedStartLoop(TInt& aRunning);

                IMPORT_C virtual void OnStarting();

                IMPORT_C virtual void OnStopping();

                IMPORT_C virtual void Reserved_1();

                IMPORT_C virtual void Reserved_2();

            private:

                // private interface used through by CActiveSchedulerWait objects

                friend class CActiveSchedulerWait;

                static void OwnedStart(CActiveSchedulerWait& aOwner);

            protected:

                inline TInt Level() const;

            private:

                TInt iLevel;

                TPriQue<CActive> iActiveQ;

                };

             

            我們并沒(méi)有看到靜態(tài)的成員來(lái)表示線程,但是卻有一個(gè)static函數(shù)CActiveScheduler* Current();返回當(dāng)前線程的調(diào)度器.

            現(xiàn)在猜想奧秘就在這個(gè)函數(shù)是怎么實(shí)現(xiàn)的。這個(gè)靜態(tài)的函數(shù)怎么就能得到當(dāng)前這個(gè)運(yùn)行線程的調(diào)度器,而不是別的線程的調(diào)度器。我們可以猜想,肯定是Current()內(nèi)部實(shí)現(xiàn)能取到當(dāng)前線程的標(biāo)識(shí)信息.用這個(gè)標(biāo)識(shí),靜態(tài)函數(shù)能取到這個(gè)線程的CActiveScheduler.這個(gè)具體如何實(shí)現(xiàn)呢?

            答案就是:當(dāng)前線程的線程ID可以這樣得到:

            創(chuàng)建一個(gè)缺省的線程對(duì)象:

            RThread thread;

            取得當(dāng)前線程的ID:

            TThreadId threadId = thread.Id();

            能得到當(dāng)前線程的threadId,當(dāng)然可以得到和當(dāng)前線程關(guān)聯(lián)的CActiveScheduler。因此以上兩個(gè)問(wèn)題也就迎刃而解了,在一個(gè)線程內(nèi)調(diào)用CActiveScheduler::Start(),CActiveScheduler::Stop()開(kāi)啟的就是當(dāng)前線程。

            既然回復(fù)了上面的問(wèn)題,那么我們自然就能明確,在一個(gè)線程內(nèi)是不能通過(guò)StartStop函數(shù)來(lái)開(kāi)啟和停止另一個(gè)線程內(nèi)的活動(dòng)對(duì)象規(guī)劃器CActiveScheduler

             

            補(bǔ)充點(diǎn)其他東西:

            Symbian操作系統(tǒng)中,每個(gè)進(jìn)程都有一個(gè)或多個(gè)線程。線程是執(zhí)行的基本單位。一個(gè)進(jìn)程的主線程是在進(jìn)程啟動(dòng)時(shí)生成的。Symbian屬于搶占式多任務(wù)操作系統(tǒng),這意味著每個(gè)線程都有自己的執(zhí)行時(shí)間,直到系統(tǒng)將CPU使用權(quán)給予其他線程。當(dāng)系統(tǒng)調(diào)度時(shí),具有最高優(yōu)先權(quán)的線程將首先獲得執(zhí)行。

            進(jìn)程邊界是受內(nèi)存保護(hù)的。所有的用戶進(jìn)程都有自己的內(nèi)存地址空間,同一進(jìn)程中的所有線程共享這一空間,用戶進(jìn)程不能直接訪問(wèn)其他進(jìn)程的地址空間。

            每個(gè)線程都有它自己的stackheap,這里heap可以是私有的,也可以被其他線程共享。應(yīng)用程序框架生成并安裝了一個(gè)active scheduler,并且為主線程準(zhǔn)備了清除棧。如果沒(méi)有使用框架(如編寫(xiě)exe程序)那就要手動(dòng)生成這些了。

            Symbian操作系統(tǒng)專為單線程應(yīng)用優(yōu)化,因此強(qiáng)烈推薦使用“活動(dòng)對(duì)象”代替多線程。

            posted @ 2008-10-11 20:34 frank.sunny 閱讀(2693) | 評(píng)論 (2)編輯 收藏

             

            如何在C++中調(diào)用C的代碼

             

            以前曾經(jīng)總結(jié)過(guò)一篇(http://www.shnenglu.com/franksunny/archive/2007/11/29/37510.html),關(guān)于在C中如何調(diào)用C++的代碼,當(dāng)時(shí)并未做完全的展開(kāi),只是簡(jiǎn)單的做了下調(diào)試,最近看到一個(gè)題目要求實(shí)現(xiàn)CC++中代碼的互相調(diào)用,其結(jié)果雖然都是通過(guò)extern “C”來(lái)實(shí)現(xiàn),但是具體還是有些差別的。

            先對(duì)C中調(diào)用C++代碼作個(gè)簡(jiǎn)單回顧:

            1、              對(duì)于C++中非類的成員函數(shù),可以簡(jiǎn)單的在函數(shù)聲明前面加extern “C”,通常函數(shù)聲明位于頭文件中,當(dāng)然也可以將聲明和函數(shù)定義一起放在cpp,在沒(méi)有聲明的情況下,直接在定義前添加extern “C”也可

            2、              對(duì)于C++類的成員函數(shù),則需要另外做一個(gè)cpp文件,將需要調(diào)用的函數(shù)進(jìn)行包裝

            以上兩項(xiàng)的實(shí)例參看前面C中如何調(diào)用C++代碼的文章。

            要實(shí)現(xiàn)C++中調(diào)用C的代碼,具體操作:

            對(duì)于C中的函數(shù)代碼,要么C代碼的頭文件進(jìn)行修改,在其被含入C++代碼時(shí)在聲明中加入extern “C”或者C++代碼中重新聲明一下C函數(shù),重新聲明時(shí)添加上extern “C”

            通過(guò)以上的說(shuō)明,我明白一點(diǎn),那就是extern “C”頭一定是加在C++的代碼文件中才能起作用的

             

            下面分析一下這個(gè)現(xiàn)象的實(shí)質(zhì)原因:

            C編譯器編譯函數(shù)時(shí)不帶函數(shù)的類型信息,只包含函數(shù)符號(hào)名字,如C編譯器把函數(shù)int a(float x)編譯成類似_a這樣的符號(hào),C連接器只要找到了調(diào)用函數(shù)的符號(hào),就可以連接成功,它假設(shè)參數(shù)類型信息是正確的,這是C編譯連接器的缺點(diǎn)。而C++編譯器為了實(shí)現(xiàn)函數(shù)重載,編譯時(shí)會(huì)帶上函數(shù)的類型信息,如他把上面的a函數(shù)可能編譯成_a_float這樣的符號(hào)為了實(shí)現(xiàn)重載,注意它還是沒(méi)有帶返回值得信息,這也是為什么C++不支持采用函數(shù)返回值來(lái)區(qū)別函數(shù)重載的原因之一,當(dāng)然,函數(shù)的使用者對(duì)函數(shù)返回值的處理方式(如忽略)也是重要原因。

            基于以上,C調(diào)用C++,首先需要用封裝函數(shù)把對(duì)C++的類等的調(diào)用封裝成C函數(shù)以便C調(diào)用,于是extern "C"的作用是:讓編譯器知道這件事,然后C語(yǔ)言的方式編譯和連接封裝函數(shù)通常是把封裝函數(shù)用C++編譯器按C++方式編譯,用了extern "C" 后,編譯器便依C的方式編譯封裝接口,當(dāng)然接口函數(shù)里面的C++語(yǔ)法還是按C++方式編譯;對(duì)于C語(yǔ)言部分--調(diào)用者,還是按C語(yǔ)言編譯;分別對(duì)C++接口部分和C部分編譯后,再連接就可以實(shí)現(xiàn)C調(diào)用C++)。相反,C++調(diào)用C函數(shù),extern "C" 的作用是:讓C++連接器找調(diào)用函數(shù)的符號(hào)時(shí)采用C的方式,即使用_a而不是_a_float來(lái)找調(diào)用函數(shù)。

             

            具體示例請(qǐng)見(jiàn)http://www.shnenglu.com/Files/franksunny/CCallCpp.rar

            注:如果你用VC6.0編譯附件時(shí)遇到類似“fatal error C1010: unexpected end of file while looking for precompiled header directive”報(bào)錯(cuò)的話,請(qǐng)將bb.c文件做如下處理右鍵點(diǎn)擊項(xiàng)目工程中的該文件,選擇setting,在c/c++欄,選擇PreCompiled headers,然后設(shè)置第一選項(xiàng),選擇不使用預(yù)編譯頭。

             

            posted @ 2008-10-10 17:54 frank.sunny 閱讀(8989) | 評(píng)論 (1)編輯 收藏
                 摘要:   活動(dòng)對(duì)象框架原理   一、概述: Symbian OS是一個(gè)多任務(wù)的操作系統(tǒng),那么為了實(shí)現(xiàn)多任務(wù),同時(shí)使系統(tǒng)能夠快速響應(yīng),高效的進(jìn)行事件處理,并減輕應(yīng)用程序員的工作負(fù)擔(dān)(申請(qǐng)大多數(shù)耗時(shí)的操作(例如文件系統(tǒng))由服務(wù)提供器來(lái)完成,服務(wù)提供器完成程序員提交的請(qǐng)求后,將會(huì)返回給程序員一個(gè)成功或失敗的信號(hào)。),Symbian OS特意引入了活動(dòng)對(duì)象的概念。 服務(wù)提供器API...  閱讀全文
            posted @ 2008-10-09 20:42 frank.sunny 閱讀(1826) | 評(píng)論 (0)編輯 收藏

            這種在Symbian C/S架構(gòu)中,服務(wù)器程序與客戶UI進(jìn)程主動(dòng)通信中用的比較多。

            對(duì)于在往UI框架應(yīng)用程序發(fā)送消息,可以通過(guò)Symbian OSApplication Architecture Services可以進(jìn)行應(yīng)用程序間的通信,主要用到的類包括:TApaTaskListTApaTask

            TApaTaskList:用于訪問(wèn)設(shè)備中正在運(yùn)行的任務(wù)(假如有些任務(wù)隱藏了的話,那么通過(guò)這種方法也無(wú)法進(jìn)行訪問(wèn))。

            TApaTask:表示設(shè)備中某個(gè)運(yùn)行的任務(wù),通過(guò)與程序關(guān)聯(lián)的窗口組(window group)標(biāo)識(shí)。

            具體的解決方案:

            發(fā)送消息端:使用TApaTaskList找到等待接收消息的任務(wù),TApaTaskList::FindApp()提供了兩個(gè)重載版本,可以使用程序的標(biāo)題,也可以使用程序的UID進(jìn)行查找。獲得需要發(fā)消息的任務(wù)后就可以通過(guò)TApaTask:: SendMessage()發(fā)送消息了,它有兩個(gè)參數(shù),第一個(gè)參數(shù)用于標(biāo)識(shí)消息,第二個(gè)參數(shù)是一個(gè)描述符的引用,可以用來(lái)提供不同消息時(shí)附加的具體信息。

            TUid uid( TUid::Uid( 0x0116C9D3 ) );

            TApaTaskList taskList( iCoeEnv->WsSession() );

            TApaTask task = taskList.FindApp(uid );

             

            if( task.Exists() ) //判斷任務(wù)是否正在運(yùn)行

            {

                LIT8( KTestMsg, "CustomMessage" );

                TUid msgUid( TUid::Uid( 1 ) );

                task.SendMessage( uid, KTestMsg );

            }

             

            接收消息端可以使用如下兩種方案:

            第一種方案:由于MCoeMessageObserver是處理來(lái)自窗口服務(wù)器消息的接口類,而CEikAppUi已經(jīng)繼承自MCoeMessageObserver,所以我們只需要在自己的UI類中重現(xiàn)實(shí)現(xiàn)MCoeMessageObserver的唯一成員函數(shù)HandleMessageL()用來(lái)處理接收到的消息即可,代碼如下:

            MCoeMessageObserver::TMessageResponse CXXXAppUi::HandleMessageL(TUint32 aClientHandleOfTargetWindowGroup, TUid aMessageUid, const TDesC8& aMessageParameters)

            {

                _LIT( KFormatStr, "%x" );

                TBuf<32> bufUid;

                TBuf<32> bufPara;

                bufUid.AppendFormat( KFormatStr, aMessageUid.iUid );

                bufPara.Copy( aMessageParameters );

                iEikonEnv->InfoWinL( bufUid, bufPara );

                return MCoeMessageObserver::EMessageHandled;

            }

             

            第二種方案:由于TApaTask::SendMessage()發(fā)送的消息可以被CEikAppUI的成員函數(shù)ProcessMessageL()攔截并處理,不過(guò)必須在沒(méi)有重載HandleMessageL()函數(shù)的前提下,而且函數(shù)ProcessMessageL()只負(fù)責(zé)攔截消息標(biāo)識(shí)為KUidApaMessageSwitchOpenFileValueKUidApaMessageSwitchCreateFileValue的這兩個(gè)消息,其它標(biāo)識(shí)值的消息不會(huì)被傳到ProcessMessageL()中,所以這種方案?jìng)€(gè)人覺(jué)得很受限制,不自由,還是采用第一種方案好,具體代碼代碼如下:

            //發(fā)送:

            TUid uid( TUid::Uid( 0x0116C9D3 ) );

            TApaTaskList taskList( iCoeEnv->WsSession() );

            TApaTask task = taskList.FindApp(uid );

             

            if( task.Exists() ) //判斷任務(wù)是否正在運(yùn)行

            {

                LIT8( KTestMsg, "CustomMessage" );

                //這里的Uid不能使用自定義的,而且只有系統(tǒng)提供的兩個(gè)

                TUid msgUid( TUid::Uid(KUidApaMessageSwitchCreateFileValue) );

                task.SendMessage( uid, KTestMsg );

            }

             

            //接收:

            void CXXXAppUi::ProcessMessageL(TUid aUid,const TDesC8& aParams)

            {

                RFileLogger iLog;

                iLog.Connect();

                iLog.CreateLog(_L("tb"), _L("UpdateListener2.txt"), EFileLoggingModeOverwrite);

                iLog.Write(_L("smms appui"));

             

                if (aUid.iUid == KUidApaMessageSwitchCreateFileValue)

                {

                    TBuf<256> buf;

                    buf.Copy(aParams);

                    iLog.Write(aParams);

                    BringMeToFront();

                    ShowCreateFile(buf,CFileMonitorEngine::EImageType);

                }

                else

                {

                    CAknViewAppUi::ProcessMessageL(aUid,aParams);

                }

                iLog.Close();

            }


            明天就是中秋了,恭祝大家中秋節(jié)快樂(lè)
            posted @ 2008-09-13 07:46 frank.sunny 閱讀(2081) | 評(píng)論 (1)編輯 收藏
                 摘要:   關(guān)于vCard和Symbian上的操作   前陣子關(guān)于Symbian通訊錄操作的時(shí)候曾提到vCard,但是由于當(dāng)時(shí)項(xiàng)目比較緊,所以也沒(méi)有時(shí)間整理,今天特意抽了點(diǎn)時(shí)間小試了一下,發(fā)現(xiàn)很多手機(jī)(我試了下索愛(ài)的和諾基亞的)如果選中通訊錄中的記錄發(fā)送聯(lián)系人或者發(fā)送名片之類的操作,就是會(huì)以vcf文件格式進(jìn)行發(fā)送。不過(guò)手機(jī)上的vcf文件通常是用UTF-8編碼的,所以雖然可以用ou...  閱讀全文
            posted @ 2008-09-13 07:20 frank.sunny 閱讀(3716) | 評(píng)論 (0)編輯 收藏
                 摘要: Symbian OS平臺(tái)簡(jiǎn)體漢字編程編碼處理   相信大家都在處理symbian中文顯示的時(shí)候遇到了編碼的問(wèn)題,我現(xiàn)在就給總結(jié)一下這種問(wèn)題的解決方法: 字符串編碼中文表示常用的有:GB2312,GBK,Unicode,UTF-8 其中GBK是GB2312的超集,也就是涵蓋了GB2312編碼的所有內(nèi)容; UTF-8是Unicode的在網(wǎng)絡(luò)傳輸中的一種編碼格式。 如果我們使用...  閱讀全文
            posted @ 2008-09-10 20:11 frank.sunny 閱讀(4125) | 評(píng)論 (1)編輯 收藏
                 摘要: Symbian OS中的消息存儲(chǔ)與常用操作 說(shuō)明:本文前面消息的基本知識(shí)主要參考《Series60應(yīng)用程序開(kāi)發(fā)》中的有關(guān)內(nèi)容,后面是前段做MTM開(kāi)發(fā)中用到的代碼。 一、消息存儲(chǔ)基本知識(shí) Symbian OS提供的消息傳送架構(gòu)基于Client/Server機(jī)制,服務(wù)器負(fù)責(zé)管理手機(jī)上的各種消息,在進(jìn)行消息相關(guān)操作之前我們需要了解Symbian OS是如何組織和存儲(chǔ)消息的。 手機(jī)中的各種消息...  閱讀全文
            posted @ 2008-07-30 21:04 frank.sunny 閱讀(3258) | 評(píng)論 (2)編輯 收藏
                 摘要:   Symbian OS應(yīng)用開(kāi)發(fā)學(xué)習(xí)筆記之通訊錄(電話薄Contacts)   Symbian OS通訊錄模型 Symbian OS手機(jī)的通訊錄采用文件方式存儲(chǔ),用symbian自己的說(shuō)法就是通訊錄數(shù)據(jù)庫(kù)。每個(gè)Symbian OS手機(jī)都有一個(gè)默認(rèn)的通訊錄數(shù)據(jù)庫(kù),這個(gè)通訊錄數(shù)據(jù)庫(kù)在2nd和3rd兩個(gè)版本手機(jī)中的位置是不同的,前者是c:\ system\data\Conta...  閱讀全文
            posted @ 2008-06-27 08:05 frank.sunny 閱讀(6442) | 評(píng)論 (8)編輯 收藏

             

            今天接到電話面試,被問(wèn)到幾個(gè)問(wèn)題,汗顏之余,小結(jié)一下

            1、      多態(tài)是如何實(shí)現(xiàn)綁定的

            多態(tài)的綁定可以分為運(yùn)行是多態(tài)和編譯時(shí)多態(tài)

            編譯時(shí)的多態(tài)性

            編譯時(shí)的多態(tài)性是通過(guò)重載來(lái)實(shí)現(xiàn)的。對(duì)于非虛的成員來(lái)說(shuō),系統(tǒng)在編譯時(shí),根據(jù)傳遞的參數(shù)、返回的類型等信息決定實(shí)現(xiàn)何種操作。

            運(yùn)行時(shí)的多態(tài)性

            運(yùn)行時(shí)的多態(tài)性就是指直到系統(tǒng)運(yùn)行時(shí),才根據(jù)實(shí)際情況決定實(shí)現(xiàn)何種操作。C#中,運(yùn)行時(shí)的多態(tài)性通過(guò)虛成員實(shí)現(xiàn)。

            編譯時(shí)的多態(tài)性為我們提供了運(yùn)行速度快的特點(diǎn),而運(yùn)行時(shí)的多態(tài)性則帶來(lái)了高度靈活和抽象的特點(diǎn)。

            今天才正式弄清楚原來(lái)虛函數(shù)是可以實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)的,以前只知道虛函數(shù)可以使得基類對(duì)象的的方法調(diào)用派生類的方法。

            2、      析構(gòu)函數(shù)是虛函數(shù)的優(yōu)點(diǎn)是什么

            C++開(kāi)發(fā)的時(shí)候,用來(lái)做基類的類的析構(gòu)函數(shù)一般都是虛函數(shù)。可是,為什么要這樣做呢?下面用一個(gè)小例子來(lái)說(shuō)明:

            有下面的兩個(gè)類:

            class ClxBase

            {

            public:

                ClxBase() {};

                virtual ~ClxBase() {};

             

                virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };

            };

             

            class ClxDerived : public ClxBase

            {

            public:

                ClxDerived() {};

                ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };

             

                void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };

            };

             

            代碼

             

            ClxBase *pTest = new ClxDerived;

            pTest->DoSomething();

            delete pTest;

             

            輸出結(jié)果是:

             

            Do something in class ClxDerived!

            Output from the destructor of class ClxDerived!

             

            這個(gè)很簡(jiǎn)單,非常好理解。

            但是,如果把類ClxBase析構(gòu)函數(shù)前的virtual去掉,那輸出結(jié)果就是下面的樣子了:

            Do something in class ClxDerived!

            也就是說(shuō),類ClxDerived的析構(gòu)函數(shù)根本沒(méi)有被調(diào)用!一般情況下類的析構(gòu)函數(shù)里面都是釋放內(nèi)存資源,而析構(gòu)函數(shù)不被調(diào)用的話就會(huì)造成內(nèi)存泄漏。我想所有的C++程序員都知道這樣的危險(xiǎn)性。當(dāng)然,如果在析構(gòu)函數(shù)中做了其他工作的話,那你的所有努力也都是白費(fèi)力氣。

            所以,文章開(kāi)頭的那個(gè)問(wèn)題的答案就是--這樣做是為了當(dāng)用一個(gè)基類的指針刪除一個(gè)派生類的對(duì)象時(shí),派生類的析構(gòu)函數(shù)會(huì)被調(diào)用。

            當(dāng)然,并不是要把所有類的析構(gòu)函數(shù)都寫(xiě)成虛函數(shù)。因?yàn)楫?dāng)類里面有虛函數(shù)的時(shí)候,編譯器會(huì)給類添加一個(gè)虛函數(shù)表,里面來(lái)存放虛函數(shù)指針,這樣就會(huì)增加類的存儲(chǔ)空間。所以,只有當(dāng)一個(gè)類被用來(lái)作為基類的時(shí)候,才把析構(gòu)函數(shù)寫(xiě)成虛函數(shù)。

             

            說(shuō)實(shí)話,這個(gè)也是今天才深刻認(rèn)識(shí)到的。

             

            當(dāng)然還問(wèn)到很多數(shù)據(jù)結(jié)構(gòu)和算法方面(空間復(fù)雜度和時(shí)間復(fù)雜度之類的東東,說(shuō)真的也是基礎(chǔ)性的)的問(wèn)題,至于那些東西,自己說(shuō)實(shí)話拋開(kāi)沒(méi)用他們已經(jīng)很長(zhǎng)時(shí)間了,真可以說(shuō)忘的差不多了,考這種真的很怕,也怪平時(shí)沒(méi)怎么用到。不知道大家用的多不?

            好久沒(méi)有正式參加過(guò)面試了,今天突然來(lái)一次覺(jué)得自己基礎(chǔ)還是不夠扎實(shí)。

            posted @ 2008-05-19 20:30 frank.sunny 閱讀(18151) | 評(píng)論 (12)編輯 收藏
            僅列出標(biāo)題
            共7頁(yè): 1 2 3 4 5 6 7 

            常用鏈接

            留言簿(13)

            隨筆分類

            個(gè)人其它博客

            基礎(chǔ)知識(shí)鏈接

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久综合综合久久狠狠狠97色88| 亚洲AV无码久久精品成人| 丁香狠狠色婷婷久久综合| 99久久精品免费看国产一区二区三区| 99久久无码一区人妻| 国产欧美久久久精品影院| 99精品国产综合久久久久五月天| 国产精品一区二区久久不卡| 精品无码久久久久久国产| 伊人久久大香线蕉av不卡| www亚洲欲色成人久久精品| 国产毛片欧美毛片久久久| 97久久精品人人做人人爽| 久久久亚洲欧洲日产国码是AV| 久久香蕉一级毛片| 伊人久久大香线蕉av不变影院| 久久乐国产精品亚洲综合| 国产精品久久久久久福利69堂| 91麻豆国产精品91久久久| 国产AV影片久久久久久| 奇米影视7777久久精品| 少妇人妻综合久久中文字幕| 精品久久久久久国产牛牛app| 久久精品一本到99热免费| 久久人人爽人人人人片av| 久久综合久久性久99毛片| 久久免费精品视频| 精品熟女少妇av免费久久| 99久久无色码中文字幕人妻| 国产精品久久久久久久久软件| 激情五月综合综合久久69| 伊人久久免费视频| 久久久青草久久久青草| 国产精品久久亚洲不卡动漫| 久久99国产综合精品女同| 国产精品一区二区久久国产| 久久无码人妻一区二区三区午夜| 日日躁夜夜躁狠狠久久AV| 久久丫精品国产亚洲av不卡| 久久精品国产久精国产思思| 久久精品国产亚洲AV电影|