• <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>
            隨筆 - 2, 文章 - 73, 評(píng)論 - 60, 引用 - 0
            數(shù)據(jù)加載中……

            [S60]ARM平臺(tái)獨(dú)有問(wèn)題 Writable Static Data in DLLs

            [S60] ARM平臺(tái)獨(dú)有問(wèn)題 Writable Static Data in DLLs
            2007-07-08 16:59
            在編譯arm平臺(tái)程序的時(shí)候,出現(xiàn)如下錯(cuò)誤提示:
            ERROR: Dll 'AppName[UID].APP' has initialised data.
            或者:
            ERROR: Dll 'AppName[UID].APP' has uninitialised data.
            (擴(kuò)展名APP的應(yīng)用程序其實(shí)也是一個(gè)DLL。)

            而在為模擬器編譯的時(shí)候,這個(gè)問(wèn)題不會(huì)出現(xiàn)。這曾經(jīng)導(dǎo)致我在完成完整的設(shè)計(jì),編碼和調(diào)試后,
            被迫放棄原有設(shè)計(jì)。

            從這條錯(cuò)誤信息的字面意思是什么也看不出來(lái)的。
            initialised 和 uninitialised都一樣有問(wèn)題。
            其實(shí)真正的含義是Dll里存在可寫的全局變量。

            大家知道在程序運(yùn)行的時(shí)候,DLL只會(huì)被裝載一次。在Windows平臺(tái),每個(gè)進(jìn)程都有自己獨(dú)立的DLL空間。也就是說(shuō),不同進(jìn)程裝載同一個(gè)DLL,互相之間是獨(dú)立的。只有在一個(gè)進(jìn)程內(nèi),才是共享的。但是S60平臺(tái)的設(shè)計(jì)是所有進(jìn)程都共享同一個(gè)DLL空間。這樣的設(shè)計(jì)顯然是出于節(jié)約內(nèi)存的目的,是很有必要的。但是這樣就帶來(lái)一個(gè)問(wèn)題,那就是DLL里不可以有可寫的全局變量,否則就要造成混亂。A進(jìn)程對(duì)變量的改寫會(huì)直接影響到B進(jìn)程,這是程序設(shè)計(jì)者所不愿意看到的。所以,S60平臺(tái)的編譯器就禁止了在DLL內(nèi)申明可寫全局變量。但是全局變量還是可以用的,只要加上const申明即可。

            一般來(lái)說(shuō),在做DLL設(shè)計(jì)的時(shí)候,的確不鼓勵(lì)使用可寫全局變量。即使是windows平臺(tái),DLL的可寫全局變量也會(huì)在不同模塊之間帶來(lái)問(wèn)題。當(dāng)遇到這個(gè)編譯器錯(cuò)誤的時(shí)候,應(yīng)該設(shè)法修改設(shè)計(jì),回避使用全局變量。

            但是因?yàn)锳PP實(shí)際上也是DLL,這就導(dǎo)致連S60的主程序也不能使用可寫的全局變量,這個(gè)在某些時(shí)候就成了問(wèn)題,全局變量畢竟是一個(gè)重要的實(shí)現(xiàn)手段。對(duì)此,S60提供了線程局部存儲(chǔ)(
            thread local storage)來(lái)解決問(wèn)題。
            TLS的關(guān)鍵是兩個(gè)函數(shù):
            void Dll::SetTls(void*)和void* Dll::Tls()
            SetTls用于將任意類型的指針保存到線程局部存儲(chǔ)中,而Tls()則取出該指針。
            指針指向在堆上分配的一塊內(nèi)存。一個(gè)線程只能有一個(gè)局部存儲(chǔ)變量。所以,如果你有很多全局變量,就要定義一個(gè)結(jié)構(gòu),把所有的全局變量封裝在其中。這是挺別扭的,不過(guò)S60 3rd據(jù)說(shuō)就支持dll的可寫全局變量了。

            tls樣例代碼:

            設(shè)置
            GlobalData* p = new GlobalData();
            if ( p )
            {
               Dll::SetTls( p );
            }

            使用
            GlobalData* p = (GlobalData*) Dll::Tls();

             

            在Symbian上如何定義全局變量

            方法1(推薦)把這個(gè)變量定義成AppUi類的私有成員,在創(chuàng)建view時(shí)將這個(gè)變量傳引用(或傳指針)到view中,這樣view就能隨時(shí)訪問(wèn)它了。

            方法2.把這個(gè)變量定義成AppUi類的私有成員,并為它寫公共的訪問(wèn)函數(shù)
            // CMyAppUi
            public: // new methods
               TInt Share(); // return iShare
            private:
            JAVA手機(jī)網(wǎng)[www.cnjm.net]   TInt iShare;
            在View里通過(guò)下面的方式訪問(wèn)這個(gè)變量:
            // 如果View繼承自CAknView
            CMyAppUi* appUi = static_cast<CMyAppUi*>(AppUi());
            appUi->Share(); // :)
            // 如果View是其它類型
            CMyAppUi* appUi = static_cast<CMyAppUi*>(CCoeEnv::Static()->AppUi());
            appUi->Share(); // :)
            方法3.使用單態(tài)類,參考諾基亞論壇上的文檔:
            Tip Of The Month: How To Implement A Singleton Class In Symbian OS



             

            How to implement a singleton class in Symbian OS        ID: TTS000222

            Version 1.1
            Published at www.forum.nokia.com on October 19, 2006.

            Overview

            The singleton pattern is one of the best-known patterns in software engineering. Essentially, a singleton is a class which only allows a single instance of itself to be created, and usually gives simple access to that instance.

            How to use thread local storage (TLS) to implement a singleton class

            In Symbian OS, each DLL that is loaded in each thread has a machine word of thread-specific memory that can be written to and read — but no other static memory, which is why you can't have static class member variables. Since static class member variables are usually used to implement the singleton pattern, in Symbian OS we have to get around this, for instance by using TLS.

            The following code demonstrates a singleton object whose NewL function uses TLS to test whether an object of its own type has been created. If it has, it simply returns the pointer stored in TLS, converted to its own type. If not, it instantiates an object of its own type, stores it in TLS, and then returns it.

            Note that this assumes that no other class in the DLL that includes this class uses TLS. If this is not the case, you must write a singleton manager class, which uses TLS to store a pointer to a structure of pointers to all the singleton classes that the program needs.

            Example 1: Singleton implementation based on TLS

              ==============

              CMySingleton.h

              ==============

             

              class CMySingleton : public CBase

                  {

              public: // constructor and destructor

                  static CMySingleton* NewL();

                  virtual ~CMySingleton();

              private: // constructors

                  CMySingleton(); // private because of the singleton pattern; it is

                                  // guaranteed that only NewL will call it

                  void ConstructL();

              public: // other functions

                  ...

              private: // other functions

                  ...

              private: // data

                  ...

                  }

             

              ================

              CMySingleton.cpp

              ================

             

              CMySingleton::CMySingleton* NewL()

                  {

                  CMySingleton* singleton;

                  // Check thread local storage:

                  if ( Dll::Tls() == NULL )

                      {

                      // TLS is still null, which means that no CMySingleton has

                      // been instantiated yet.  Do so now, and return that

                      // instance:

                      singleton = new ( ELeave ) CMySingleton();

                      CleanupStack::PushL( singleton );

                      singleton->ConstructL();

                      CleanupStack::Pop( singleton );

                      // Store a pointer to the new instance in thread local storage:

                      TInt err = Dll::SetTls( static_cast<TAny*>( singleton ) );

                      if ( err == KErrNone )

                          {

                          return singleton;

                          }

                      else

                          {

                          delete instance;

                          User::Leave( err );

                          return NULL;

                          }

                      }

                  else

                      {

                      // CMySingleton has been instantiated once already, so return

                      // that instance:

                      singleton = static_cast<CMySingleton*>( Dll::Tls() );

                      return singleton;

                      }

                  }

             

            TLS on S60 3rd Edition

            Since applications from S60 3rd Edition onwards are implemented as EXE programs, Dll::Tls() is not available anymore. Instead, TLS functionality is implemented in UserSvr class (e32svr.h):

            static TInt DllSetTls(TInt aHandle, TAny *aPtr);

            static TAny *DllTls(TInt aHandle);

            static void DllFreeTls(TInt aHandle);

            Note that EXE programs can contain writeable static data, but this is not recommended to be used except as a last resort.

            Using class CCoeStatic to implement a singleton class

            A simpler way of implementing singletons than using TLS is possible for those classes which use the CCoeEnv class. Since CCoeEnv is a part of the UI control framework, this concerns only applications, not application engines.

            This applies also to S60 3rd Edition and later editions.

            Example 2: Singleton implementation based on CCoeStatic

              ==============

              CMySingleton.h

              ==============

             

              /**

               * Example implementation of a singleton class by means of inheriting

               * from CCoeStatic.

               */

              class CMySingleton : public CCoeStatic

                  {

             

              public: // constructors and destructor   

             

                  /**   

                   * Returns an instance of this class. When called for the first

                   * time, a new instance is created and returned.  After that,

                   * calling InstanceL returns the same instance that was created

                   * earlier.

                   *  

                   * @return A pointer to a CMySingleton object   

                   */   

                  static CMySingleton* InstanceL();   

             

              private: // constructor

             

                  /**   

                   * Default constructor is private because we are using the

                   * singleton design pattern.

                   */   

                  CMySingleton();   

             

                  ...

             

                  }

             

             

              ================

              CMySingleton.cpp

              ================

             

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

              // CMySingleton::CMySingleton

              // C++ default constructor. It is private because we are using the

              // singleton design pattern.

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

              CMySingleton::CMySingleton()

                  : CCoeStatic( KUidMySingleton )

                  {

                  }

             

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

              // CMySingleton::InstanceL

              // Returns an instance of this class. When called for the first time,

              // a new instance is created and returned.  After that, calling

              // InstanceL returns the same instance that was created earlier.

              // Note that the UID passed to CCoeEnv::Static needs to be unique.

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

              CMySingleton* CMySingleton::InstanceL()

                  {

                  CMySingleton* instance = static_cast<CMySingleton*>

                      ( CCoeEnv::Static( KUidMySingleton ) );

                  if ( !instance )

                      {

                      instance = new ( ELeave ) CMySingleton;

                      CleanupStack::PushL( instance );

                      instance->ConstructL();

                      CleanupStack::Pop();

                      }

                  return instance;

                 }

            posted on 2008-06-02 20:23 郭天文 閱讀(955) 評(píng)論(0)  編輯 收藏 引用 所屬分類: S60

            国产精久久一区二区三区| 人妻精品久久久久中文字幕| 美女写真久久影院| 人妻少妇精品久久| 99久久免费国产特黄| 思思久久99热免费精品6| 久久久精品人妻一区二区三区蜜桃| 成人午夜精品久久久久久久小说 | 久久久久噜噜噜亚洲熟女综合| 要久久爱在线免费观看| 亚洲国产精品久久| 亚洲午夜久久久久妓女影院| 亚洲成人精品久久| 久久一日本道色综合久久| 欧美激情精品久久久久久| 久久久久久综合一区中文字幕 | 99久久国产热无码精品免费| 久久亚洲天堂| 久久久久夜夜夜精品国产| 久久亚洲精品中文字幕| 武侠古典久久婷婷狼人伊人| 国产国产成人久久精品| 久久精品水蜜桃av综合天堂| 国产精品乱码久久久久久软件 | 色天使久久综合网天天| 久久www免费人成精品香蕉| 97精品伊人久久久大香线蕉 | 久久93精品国产91久久综合| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 久久国产色av免费看| 武侠古典久久婷婷狼人伊人| 久久精品国产99久久丝袜| segui久久国产精品| 精品久久人人做人人爽综合| 精品九九久久国内精品| 97久久精品无码一区二区天美| 欧美牲交A欧牲交aⅴ久久 | 久久综合给合综合久久| 久久久久无码精品国产app| 久久久网中文字幕| 性高湖久久久久久久久AAAAA|