Rawu G's thinking

此刻 只有点燃

博客园 首页 新随笔 联系 订阅 管理

Symbian os basic

* BASIC OPERATION
* PROGRAM MODULE
* CLASS

symbian os is object oriented and use c++ , only in the deepest layer , use asm
? symbian support mutiple inherite?
? c++ have no idea of DLL , and NOT strict demand the type's bytes
? symbian focus on the system design and ( error process and clear ) , arrange using the ROM and RAM TO slove it

OBJECT CRAETE AND DESTORY
%heap
  ? every thread has a 关联堆 (默认堆)
  almost object initial in heap is inherite the CBase class
   CBase
    零初始化
    虚析构函数
  one style:
   CMyClass* myPtr = new CMyClass;
   if (myPtr)
   {
    myPtr->Fpp();
   }
   delete myPtr;
  now the style is :
   CMyClass* myPtr=new(ELeave)CMyClass;
   myPtr->Foo();
   delete myPtr;
 
  this means if the new operation fails , program operate an "EXIT" , NOT just return the NULL.
  ? How TO manage the EXIT?
  double assign ... will cause memory leak
  double delete ... hard TO debug ...and crash in a while
   if you use "delete" aboard the dtor you must set the pointer NULL
 
 
%stack
  fit for the fixed size object .
  creater function's life is the same with the object's life
   a ecellente exp is : if any string is longer than the MAX length of the file name , put them in the heap .
  use .mmp file which create .exe file TO control .exe file's stack , with the key word epocstacksize
   this method is applicable TO the control panel's program , not fit to GUI program
   GUI program has only a small stack (20k) .
  you should avoid creating a large stack , it will waste of the resourse
  the objects we can put in the stack :
   build in type
   emun
   class do NOT need dtor
    TBuf<40> or TPtrC (only use pt NOT inclue , no need dtor)

   
 
_ERROR PROCESS AND CLEAR

symbian offer a framework  TO deal WITH the error . and it will affect every line of your coding .
your program have TO  face :
 * your coding have TO be more efficien . don't waste your RAM
 * you have TO release the Memory in time .
 * you have TO deal WITH the ocassion of NOT enough memory
 * when in that occasion ,you have TO protect the data FROM  being lost
 * if there are several operation in that occation ,you have TO ensure all these operation have released the resourse
we can use the framework TO deal WITH the input check
there is one error can NOT be dealed WITH , which is called panic , actually means program error .

&panic
 User::Panic(KPanicCategory,aPanic)
 one situation : check the pass arguments
 another situation : check the program status
 common style : use assert macro
  __ASSERT_DEBUG
  __ASSERT_ALWAYS
   ex: __ASSERT_ALWAYS(aIndex>0,Panic(EMyAppIndexNagative));
  
 
&exception and trap harness
异常退出(Leave)
use trap harness's User::Leave() the activate the Leave Mechanism
compare WITH c++
 TRAP() ---- try ... catch
 User::Leave() ---- throw
 funL() ---- fun() throw (...)
trap harness process
 come across a Leave (causing BY  User::Leave())
 find a fun above include the TRAP() OR TRAPD() macro
POINT is :
 TRAP() call a fun , according TO it's second arg
 and return an 32 bit error code , according TO it's first arg
 if no error occur ,  the error code would be KErrNone (0)
ex :
 TRAPD(error,HandelKeyL());
 if(error)
 {
  RevertUndoBuffer();
  User::Leave(error);
 }
a question :
 when a Leave happen , the auto ptr ,which is holding a heap object , will lost the control on this object .
 then a memory leak turns out .

&clearupstack
 *when TO use CleanUpStack
    control panel program have TO provide this stack
    gui app has been provided BY GUI frame
    error happens :
     CX::UseL()
     {
      CY* y = new(ELeave) CY;  //--> if Leave , x will not be released , memory leak !!!!
      delete y;
     }
     CX* x = new(ELeave) CX;  //--> if Leave , nothing wrong
     x->UseL();
     
    solution : (use CleanupStack)
  CX* x = new(ELeave) CX;
  CleanupStack::PushL(x);
  x->UseL();    //--> if Leave , x will be released as a part of Leave
  x->UseL();
  x->UseL();
  CleanupStack::PopAndDestroy();
    c++ exception handle will call the object's dtor ,so it doesn't need the cleanupstack
    more:
     CX* x1 = new(ELeave) CX;
     CleanupStack::PushL(x1);
     CX* x2 = new(ELeave) CX;
     CleanupStack::PushL(x2);
     x1->UseL();
     CleanupStack::PopAndDestroy(2); //2 means above 2 , can't larger than 2 , or will cause the panic
     
     
    DO NOT OVER USE IT
    IF A OBJECT IS A MEMBER VARIBLE DO NOT USE IT
   
    we use CleanupStack only when the object will avoid executing it's dtor.
    like the err above , when Leave happen , no object's dtor will be execute  and no object will be clean in the stack
    CleanupStatck is define in e32base.h
    Once The pointer is copied TO one member of an object , it don't need to stay in cleanupstack any more ,cause
     the object's dtor will delete the pointer .
   
  
 *the chance when CleanUpStack Leave
  Seldom
  Usually , less 10 object in cleanupstack
  And the design of CleanupStack is :
   assgin several slots , one backup slot
   give one slot TO an object, meanwhile check if the backup slot is ready
   if ready , push success
   if fail , cause Leave
  so no chance happen the inaffecion slot(memory??)
  
   
  
 *CBase and CleanUpStack
  #auto varibel use CleanupStack
  #member varible use dtor
  #CBase's derives should not assign in stack , (it is only designed for heap)
   零初始化 make no sense.
   if they use in stack , what happens is unknew.
   almose CBase's derives has it's private ctor (NewL() ,NewLC());  
  
 *Two Phases Construct
    error :
  CY::CY()
  {iX = new(ELeave) CX;} // if Leave , y is not release
  
  CY* y= new(ELeave)CY; //if Leave , OK!
  CleanupStack::PushL(y);
  y->iX->UseL(); //--> if Leave , OK!
  CleanupStack::PopAndDestroy();
  
    CAN'T PUSH OBJECT IN CLEANUPSTACK BETWEEN NEW() AND CTOR()
    so DO NOT INLUDE FUNL() IN CTOR
   
    common style :
     class CZ : public CBase
     {
      public:
        static CZ* NewL();
        static CZ* NewLC();
        void ConstructL(); //--> funL() write here
        ~CZ();
      public:
        CX *iX;             
     }
     void CZ::ConstructL()
     {
       ix=new(ELeave) CX;
     }
 
 *Packeted the ConstructL() in NewL() and NewLC()
    common style :
     CZ* CZ::NewLC()
     {
      CZ* self = new(ELeave) CZ;
      CleanupStack::PushL(self);
      self->ConstructL();
      return self;
     }
     
     CZ* CZ::NewL()
     {
      CZ* self=CZ::NewLC();
      CleanupsStack::PopAndDestroy();
      return self;
     }
    after you use NewL() , you muse get in charge of the object ,cause is NOT in cleanupstack !! 
    this two fun work like factory function,a kind of static ctor
 * other style of clean up
    (do NOT understand )
   
NAME
%class
   T  --TdesC,TPoint-- like build in object , has NOT dtor , it can be assigned in stack or heap
   C  --CActive,CBase-- CBase's derive , can only be assigned in heap , use delete to release
   R  --RFile,RTimer-- Resource NOT in heap , usually AS member varible or auto varible , use Close() TO release
   M  --MGraphicsDeviceMap-- interface consis of virtual functions , Symbian only recommand the M class use mutiple inherite
   static --User,Math-- can NOT be instantiation , work AS a library
   structure --SEikControlInfo-- C style structure , but seldom use , use T class instead
%Data
   E ---- Enumeration
   K ---- Constant
   i ---- member variable
   a ---- pass argument
     ---- auto variable
%Function
   NOT Leave ---- v.
   Leave ---- L()
   LC ---- lefe an item in cleanupstack
   simple getter ---- n.
   complex getter ---- Getxxx()
   setter ---- Setxxx() or SetxxxL()
%Macro   
   XXXX_XX or __XXX or __XXXX__         
     
DESCRIPTOR
  %buffer descriptor
   data is a part of descriptor , the whole descriptor can be pack INTO stack
   TBuf , TBufC ---- char[]
   ex:
    __LIT(KTxtHelloWorld,"Hello World!");
    TBuf<16> buffer(KTxtHelloWorld);
    //remark TBuf<16> can contain 16 bytes data ,but do not mean it hold 16 bytes data .
    //       "Hello World!" length is 12 , and buffer doesn't need end of NULL
  %pointer descriptor
   data is apart FROM descriptor , descriptor can be in stack ,and the data can be in anywhere that is able TO address
   it's useful when work as pass argument , 'cause it needn't copy the whole data . h
   TPtr , TPtrC  ---- const char*
   templatelize , if the data is larger than assigned , it will return error // how it did it ?
   two sytle TO create TPtrC
      one :
       void foo(TUnit16* aBuf , TInt aLenth)  // whar TUnit16 means ????
       {
        TPtrC myPtr(aBuf,aLenth);
       }
      two :
       __LIT(KTxtHelloWorld,"Hello World!");
    TBuf<16> buffer(KTxtHelloWorld);
    TPtrC myPtr(buffer); // the length will count automatically
  %heap descriptor
   like buffer , data is a part of  descriptor , be the difference is ,it's in heap
   HBufC ---- malloc()
   actual assign size is base on the hardware unit ,so , maybe a little largerr than desire .
   it's useful when data is too large for the descriptor , or data can't be known unitl the runtime
   take care of the cleanup problem !!!
   ex:
     __LIT(KTxtHelloWorld,"Hello World!");
     HBufC* buffer = HBufC::NewL(256); // object is not in cleanupstack !!! why not !???
     *buffer = KTxtHelloWorld ;
    
   Des() :
     creat a TPtr
     ex:
    _LIT(KTxtFriends,"Friends !");
    HBufC* buffer = HBuf::NewL(256);
    *buffer = KTxtHelloWorld;
    TPtr temp = buffer->Des();
    temp.Replace(6,6,KTxtFriends);
    
   Create HBufC FROM anther descriptor  
    _LIT(KTxtHelloWorld,"hello world");
    myFunctionL(KTxtHelloWorld);
    void myFunctionL(const TDesC& aBuffer)
    {
     HBufC* mydata = aBuffer.AllocLC();
    }
   
   How large is HBufC
    base on the hardware , do NOT think the size is exactly equal TO your assignment
    
   ReAllocL
    _LIT(KTxtHelloWorld,"Hello World");
    HBufC* myData = new HBufC::NewL(16);
    *myData = KTxtHelloWorld; // HBufC can't be changed , what will happen when this line write twice ????
    myData = myData->ReAllocL(256); //it will copy the old data to new address , and release the old one
    //remember in this occasion , you must reset all the TPtr you get from Des() befroe.
       
  %constant descriptor   
   C means could NOT be modify . can only  be initialize . the only way TO change it is reassign it new data .
   but it's not exactly like  c++'s constant , it just doesn't contain the method to modify it's data .   
   nonC contain many methods TO change it's data within it's length
   HBufC has TO use special method TO change it's data
  %Base class
   *TDesC -> TBufBase ->TBufC
        ->HBufC
          -> TDes     ->TBuf
               ->TPtr
          -> TPtrC
   
   TBufC: [TDesC][Data]
   TBuf : [TDesC][TDes][Data][spaces]
   TPtrC : [TDesC][Address]
   TPtr : [TDesC][TDes][Address]
   HBufC : [TDesC][Data]
   
  %use abstract class in interface
   const TDesC& : pass unchange data
   TDes& : pass chengable data
   ex:
     void greeting(TDes& aGreeting, const TDesC& aEntity)
     {
      aGreeting.Append(aEntity);
     } 
  %Macro
   _LIT : create a TLitC object
   _L : old style , less efficiency , inclue '\0' , be eliminated
   work like TDesC:
    _LIT(KHelloRom,"Hello");
    const TDesC& helloDesC = KHelloRom;
   & : return const TDesC*
   (): return const TDesC& 
   
  %Funcetions
   basic:
   manage:
   string:
   format:
 
  %use desriptor TO save binary data
   TDesC16
   TDesC8 : usful for communication program
   
ACTIVE OBJECT
asy service
req prog -> req -> do other things (another req)-> ... -> finally hold , waiting for reply -> os wake up this prog
  -> other thread do the job       -> finish |

single thread context non-preemptive multitasking
 any time , only one event code can run . other event have TO be held
 
preemptive multitasking
   symbian support this , but Active Object is NOT used TO work in this way

schedule
 
Active Scheduler ---contain many active object ---
        active object  ---contruct---> define the priority
         ---implement--> request function
         ---request----> according TO an event  
         ---waiting---->
   ---schedule--
    ->one object left : run it
    -> many objects : run the high prior
    -> no fitable object : wait  
   ---call object's RunL()   
          --- run ------>
          --- finish ----
   ---schedure--
      
  
 
// active object (thread) -> recv events  //??? active obj control the event's prior????
//          -> run  
//          -> finish -> be controled BY activation schedule
//              ->schedule -> one object left : run it
//                  -> many objects : run the high prior
//                  -> no fitable object : wait  

in many system , multithread will be the first choice TO manager multitasking ,
 but in Symbian , Active Objct is the first choice .
 
cooperative multitasking . (difference) active obj monopolize the os

??what's the relation between Active Object and Thread ???

in fact in UI frame , all event code is run BY one Active Object's RunL()


 

 

 
 
 

posted on 2006-04-11 16:08  Rawu  阅读(1112)  评论(2编辑  收藏  举报