Download presentation
Presentation is loading. Please wait.
Published byJoanna Layng Modified over 9 years ago
1
Programming mobile devices Part II Programming Symbian devices with Symbian C++ Basic Symbian programming
2
Content of this part Basic Data Types Classes Error handling Cleanup Panics Libraries
3
Basic Data Types TInt, TUintinteger, natural word length TInt8, TInt16, TInt32 integers of 8b,16b... TUint8, TUint16, TUint32 unsigned integers of 8b,16b and 32b TInt64 64 bit integer with operators(+,-,...) TText8, TText16, TText characters TChar A character class with several methods for manipulating
4
Basic Data Types TBoolETrue / EFalse TReal32, TReal64, TReal floating point numbers (TReal64 and TReal map to double) TAnylike void, used in situations other than return values of functions
5
Classes 4 main gategories with agreed prefixes T for data type classes (e.g. TInt) C for Heap allocated classes (these inherit from CBase class) R for Resource classes (which reserve resources) M for Interface classes
6
Data Type Classes Encapsulate basic data types, such as TInt and int Usually have methods for manipulating the data e.g. TChar.loweCase() Comparison usually implemented Used instead of basic data types
7
Heap Classes All inherit from the CBase class Instantiated on the heap (using the new operation) CBase has a virtual destructor (A heap class hence has to implement it) zero initialization to all members
8
Resource classes Control resources owned by someone else e.g. client in a client/server communication usually allocated on the stack for example: RFile, RSocket, RThread Pointers to a resource, deleting the class does not usually delete the resource A resource has a reference count (How many pointers point to it)
9
Interface classes M for Mixin Abstract classes that define interfaces No member variables Methods usually pure virtual Note: Even though multiple inheritance is possible in C++, in Symbian programminig it is usually used only through interfaces. Basically: use interfaces as in Java
10
Errors and Exceptions Handling errors and exceptions is utterly important in mobile phone apps. Sources of exceptions are vast; out of memory, incoming call, empty battery... Users have high expectations of robustness of the phones and the software on them.
11
Return Codes Function's return value tells the result of excecution KErrNone -success Others include an error code that tells what went wrong, e.g. KErrNoMemory Used extensively in the APIs Still, not the best possible error handling mechanism. why ?
12
Leave/Trap Corresponding to Javas try-catch and C++ throw-catch, Symbian has a mechanism called leave-trap leave is like throw in java trap is similar to catch The mechanism is also familiar, a leave "bubbles" up the call stack like in java until it is handled by a trap (if ever)
13
Leave Programmer can call User::Leave(KErrorCode); which corresponds to throw(Exception) in java The execution of that function is stopped immediately and the control returns to the calling code. Also an API function can (and most do) leave.
14
Trap Trapping is done with a marco TRAP (or TRAPD). The code is executed onward from the next line after a TRAP (stops "bubbling") The macro takes 2 parameters: a TInt to store the leave code and the name of the function to be executed TInt LeaveResult; TRAP(LeaveResult, func1());
15
Example code void func1() { TInt result; result = somefunc(); if(result) { User::Leave(KSomeError); } void TestFunc() { TInt LeaveResult; TRAP(LeaveResult, func1()); if(LeaveResult) { // Leave happened in func1() that has to be handled }
16
Example code void func1() { TInt result; result = somefunc(); if(result) { User::Leave(KSomeError); } void TestFunc() { TRAPD(LeaveResult, func1()); // Defines LeaveResult if(LeaveResult) { // Leave happened in func1() that has to be handled }
17
Trap return values If leave does not occur KErrNone, integer 0 is returned. In trap, the return value of the function can also be saved: TRAPD(LeaveResult, resval = func1());
18
Leave functions User:: namespace has a set of static API leave functions: User::Leave(leavecode); User::LeaveNoMemory(); //KErrNoMemory User::LeaveIfError(leavecode); // If leavecode is negatice, leave with error as the reason. User::LeaveIfNull(TAny *pointer); //KErrNoMemory as the reason
19
The L suffix Symbian uses a convention to use a suffix L in functions that may leave This is to signal the programmer that it may be necessary to trap such a function Unless trapped, the code to follow might not be executed
20
A couple words about memory In contrast to Java, in C++ you must actively free any memory you have allocated. Not doing so will result in leaking of memory. Usually you use new to generate new objects and delete to destroy them Also, it is a good practice to set pointers to null after they no longer point to an object
21
Leaving and memory void func1() { CSomeObject *testObj = new CSomeObject; TInt result = testObj.somefunc(); // which may leave delete testObj; testObj = null; } void TestFunc() { TRAPD(LeaveResult, func1()); // Defines LeaveResult if(LeaveResult) { // Leave happened in func1() that has to be handled } What if?
22
Cleanup Obviously, we have a problem Since leave can result in skipping some code, we must be careful with allocated memory not to have code that leaks In previous example testObj is an automatic variable that goes out of scope when func1 exits Result: the created object is left in the memory and cannot be deleted
23
Cleanup stack The solution to our problem is something called a cleanup stack It can be thought of a storage of pointers to created objects (which might otherwise be lost) Think of it as a memory accounting device push pop
24
Cleanup stack Items that must be cleaned are pushed into the stack If leave occurs, these items are automatically popped from the stack and deleted If no leave occurs, you must pop the items yourself Watch out for double deletion
25
An example void myTestfunc() { CTestObj *obj = new CTestObj(); CleanupStack::PushL(obj); MyOtherFuncL(); // may leave CleanupStack::Pop(); delete obj; }
26
An example void myTestfunc() { CTestObj *obj = new CTestObj(); CleanupStack::PushL(obj); MyOtherFuncL(); // may leave CleanupStack::PopAndDestroy(); delete obj; // WRONG! obj already deleted }
27
Creating a cleanup stack Cleanup stack is automatically created for GUI applications For your own threads you have to create the cleanup stac yourself CTrapCleanup *clstack = CTrapCleanup::New() remember to delete the stac when finished delete clstack;
28
Object types PushL(CBase *) –delete is called when object is popped –calls the destructor of the derived class PushL(TAny *) –User::Free() is called when object is popped –destructor is not called
29
What if PushL leaves? What if there is no space in the stack? Symbian always keeps at least one free spot on the cleanup stack. If the PushL leaves, the pushed item will still be pushed to the stack Allocating the next slot may fail resulting PushL leaving
30
Complex cleanup Sometimes we have objects that require more complex cleanup than just delete PushL(TCleanupItem userCleanup) TCleanupItem is a wrapper class for a function that handles cleanup
31
Other cleanup functions CleanupClosePushL (T& obj) Pop calls obj.Close() used mainly for R classes, which require Close() to be called CleanupReleasePushL (T& obj) calls Release()
32
Other cleanup functions CleanupDeletePushL (T& obj) Using templates, the pop function calls the actual destructor of the object regardless of the type of the object Hence, the object doesn't have to be derived from CBase you should use this for all non CBase derived classes that have a destructor.
33
Templates Were created to make function code re- use possible (instead of just overloading functions) Templates basically achieve the same as a superclass in Java
34
LC functions LC suffix denotes functions that automatically push a reference of a created object to the cleanup stack For example: User::AllocLC(100) allocates memory and pushes a pointer to the cleanupstack No need for User::PushL(...)
35
Leave in object creation The new operation may fail due to inadequate memory. You can use a ELeave when calling the constructor to assure that leave occurs if object creation (new operation) fails CMyObject *obj = new (ELeave) CMyObject; Constructor itself should never leave (why?)
36
Two phase constructors After creating the object with new we call a constructor function which may leave This call can be trapped Often we name this function as ConstructL
37
ConstructL void testL() { CTestObj *o = new (ELeave) CTestObj; CleanupStack::PushL(o); o->ConstructL();... }
38
Panics Don' t panic The operating system may do that. An unrecoverable error that causes the thread to finish User::panic(const TDes &Category, TInt reason) On the device the execution ends and the device shows a dialog box
39
Libraries static (linked at build) DLLs (Dynamic Link Library) –loaded and linked at runtime –one copy is shared by multiple programs
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.