Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



Symbian OS essentials

This section lists concepts essential to working with Symbian OS, and provides links to further information about them.

Contents


Introduction

If you are new to C++ programming on Symbian OS, there are a few fundamental aspects to grasp before starting to develop applications on the platform, mostly related to the design of the operating system, which is purpose-built to run on portable devices. These, by their very nature, have limited memory, battery life and processing power. To manage these characteristics, Symbian OS provides, for example, lightweight string classes and an efficient event handling framework which will differ slightly from those offered by other operating systems.

This section will briefly summarise some of the features that you’ll find used most widely in Symbian OS code. For more detail on these and other Symbian OS APIs and techniques, you are recommended to consult the Essential Idioms section of the Symbian OS Library which also contains a number of example projects to illustrate the key points. The Resources section of this tutorial provides links to other comprehensive sources of information about Symbian OS, including the Symbian Developer Network site ('DevNet') and a range of books published by Symbian Press.

[Top]


Basic types and naming conventions

This section explains the most common Symbian OS naming conventions that are used in the example application. These conventions help to clarify the code; for instance, they tell you if a function can leave or if a class is allocated on the heap. See Naming conventions in the Symbian OS Library for more information.

If you browse through the class names typically used in Symbian OS applications, you will notice that they begin with either C, M, R or T. This letter indicates the class's characteristics, and, in particular, its cleanup requirements:

Most Symbian OS header files contain occurrences of TInt and TBool used instead of the C++ built-in types int and bool. These, and some others, are typedefs (hence the T suffix) for the fundamental C++ types. You should use these Symbian OS types rather than the C++ equivalent to guarantee compiler independence. The basic types are documented in the Symbian OS Library: see Basic Types.

As an aside, TBool represents a Boolean, whose value may be true (ETrue in Symbian OS) or false (EFalse). Because C++ interprets any non-zero value as true, you should test the value of a TBool using code like:

if (boolVal) { ... };

or

if (!boolVal) { ... };

rather than, respectively:

if (boolVal==ETrue) { ... };

or

if (boolVal==EFalse) { ... };

Many function names end with an upper-case L or LC. such as NewL() or NewLC(). This suffix is significant; the L indicates that the function (or any function it calls) can leave. The LC suffix denotes a function that allocates an object and then places it on the cleanup stack. It is important to follow this convention and name any functions you write that may leave, or may leave and return after putting objects on the cleanup stack, so code which calls your functions can take the necessary steps to ensure that memory leaks are prevented.

Parameter names begin with a lower case a (for argument) and member data names begin with lower case i (for instance). Local variables use lower case and no prefix. Constant names begin with upper case K, but enumerated constants begin with upper case E.

Finally, you will see many occurrences of IMPORT_C and EXPORT_C. These are macros that identify functions intended to be called from outside of their own DLL. IMPORT_C (in front of a class method declared in a header file) and EXPORT_C (in the corresponding method definition within a .cpp file) means that the method will be exported, so that it can be called from code in other DLLs.

In general, therefore, with the exception of virtual and inline functions, if you see a method defined in a header file for another library whose prototype is not preceded by IMPORT_C, this means that you cannot call it, even if it has a public access specifier. It will not cause a compilation error, but you will see "unresolved external" linker errors if you attempt to use it in your code.

[Top]


The cleanup stack and leaves

Instead of C++ exceptions, which were not part of the C++ standard when Symbian OS was designed, the operating system uses a lightweight exception-handling mechanism, called a ‘leave’. Leaves may occur as a result of an error condition or abnormal event, such as insufficient memory or disk space to complete a request. The leave propagates the error to a point in the calling code where it can be handled, called a TRAP harness, unwinding the call stack as it does so.

However, because of the ‘jump’, any local resources, such as memory allocated on the heap, will be ‘orphaned’, potentially leading to memory or resource handle leaks. Developers working on Symbian OS use the cleanup stack to keep track of resources to which the only pointer is an automatic variable. In the event of a leave, the cleanup stack will destroy each of the resources placed upon it.

Most leaves are caught by a TRAP harness provided by the UI framework, which will display an appropriate error message. However, there are occasions when you will need to use a TRAP harness yourself; you can find out more about them from the How to use TRAP page of the Symbian OS Library.

There are some important places in code which should never leave – namely C++ constructors and destructors. Symbian OS classes typically use two-phase construction to avoid leaves occurring in construction code; see the Two Phase Construction section of the Symbian OS Library to find out more. More information can also be found in the Symbian OS Library, under Memory Management. You should also consult a Symbian Press text book, such as Symbian OS Explained, for detailed information about, and examples of the use of, these concepts.

[Top]


Descriptors

Descriptors are Symbian OS strings, and are so-called because they are self describing. Each descriptor object holds the length of the string of data it represents as well as its 'type', which identifies the underlying memory layout of the data it holds. Because they hold length information, they do not need to be NULL-terminated and can thus be used to store binary data as well as text. Descriptors can also exist in either 8-bit ASCII or 16-bit Unicode format.

There are separate descriptor classes for data stored within the descriptor (the ‘buffer’ descriptors) or in a separate area of memory (the ‘pointer’ descriptors) and a further distinction between those which are stack-based and those created on the heap. Furthermore, there are descriptor types which may be accessed but not modified (that is, for look-up and comparison) and those which may altered by formatting, replacing or appending to the data. The following table summarises the descriptor classes:

Description

Base class

Stack buffer

Heap buffer

Pointer

Non-modifiable descriptor (16-bit by default)

TDesC(16)

TBufC<n>

HBufC

TPtrC

Modifiable descriptor (16-bit by default)

TDes(16)

TBuf<n>

RBuf

TPtr

Non-modifiable 8-bit descriptor

TDesC8

TBufC8<n>

HBufC8

TPtrC8

Modifiable descriptor 8-bit descriptor

TDes8

TBuf8<n>

RBuf8

TPtr8

Non-modifiable descriptor (explicitly 16-bit)

TDesC16

TBufC16<n>

HBufC16

TPtrC16

Modifiable descriptor (explicitly 16-bit)

TDes16

TBuf16<n>

RBuf16

TPtr16

Although there are a number of descriptor classes, which initially makes mastering the Symbian OS strings quite daunting in comparison to, for example, a scripting language, the classes all share the same base classes, as shown in the table above. The base classes provide common APIs for modifiable and non-modifiable descriptor operations, which are agnostic of the implementation type.

The filesystem browser example code which accompanies this tutorial uses a number of descriptor functions such as Format(), Append(), Zero(), SetLength() and LocateReverse(). Each SDK will also include a number of examples designed specifically to demonstrate their use. For more information about descriptors, and examples of their usage, consult the Symbian OS Library, books in the Symbian Press series or any relevant technical papers in the SDK documentation for your chosen UI platform.

[Top]


Event handling and active objects

As with applications on other operating systems, Symbian OS applications need to make both asynchronous function calls and receive asynchronous event notifications. For UI events, most of the work is done for by the Symbian OS UI framework, but other sources of asynchronicity (such as incoming data on a communications socket, interaction with hardware or use of a timer) are not wrapped by the application framework. To handle these, you typically create a class which submits a request to an asynchronous service provider and waits for its completion, supplying a function which is called when the event is received.

Symbian OS supplies a base class, CActive, to be used as the base for such classes; objects of such classes are known as active objects. The wait loop in which they run is known as the active scheduler. Consult the High Level Asynchronous Service Handling section of the Symbian OS Library for more information about Symbian OS event handling using active objects and the active scheduler. Further information and example can also be found in Symbian Press books and technical papers.

[Top]


Panics and assertions

Symbian OS uses ‘panics’ to halt the flow of program execution. Unlike a leave, which can be trapped, if a panic occurs in an application running on the phone, the application will be terminated. This does not make for a good user experience, and, for this reason, panics should only be used in assertion statements, to halt code when an unrecoverable error occurs.

Typically, assertions are used in debug builds to verify code logic and program state, and are very useful when running code on the emulator because the panic enters the debugger and allows you to investigate the root cause using just-in-time debugging. The simplest assertion statement is ASSERT, which raises a "USER 0" panic in debug builds only. __ASSERT_DEBUG and __ASSERT_ALWAYS allow you to specify what action to take if the condition fails, for debug only and for all builds respectively.

Although the macros allow you to specify the action when the assertion condition fails, the typical, and best, response is to panic and thus terminate the application. You can find out more about the use of the assertion macros from the Symbian OS Library; the Symbian OS system panic categories and numbers are documented in the System panic reference.

[Top]


Platform security and platform migration

Symbian OS v9.1 is said to be a secure platform because of changes to the operating system to extend its security model and ensure more protection against malicious or badly-implemented software. The security model operates at the software level to detect and prevent unauthorised access (to hardware, software or data) which may, for example, lock up the phone, compromise user data, or affect other software or the network. The secure platform prevents programs from acting in unacceptable ways, irrespective of whether these actions are intentional or unintentional.

The impact of platform security on application development is described in this tutorial where it is most relevant to the discussion. For example, data caging, capabilities, Secure IDs and Vendor IDs are described in the mmp file syntax section. Data caging is also covered in the pkg file format section and is illustrated by the filesystem browser application. Configuring the platform security settings of the emulator is described in The emulator. Certification and Symbian Signed are discussed in the Application signing section.

Further information is also available in the Symbian OS Library, under Platform security and from a forthcoming Symbian Press book devoted entirely to this subject.

This tutorial is based on S60 3rd Edition and UIQ 3.0. It does not cover the migration of application code written for earlier versions of either platform. You should consult the appropriate SDK for a guide to changes in the new UIQ or S60 releases and information about how to update code written for previous versions to run on the new platform.

[Top]


Other topics of interest

The previous sections have briefly introduced a few of the basic idioms used when developing C++ code on Symbian OS. There are many other aspects of the operating system that are important to know about if your application needs to use them, such as the communications programming, the filesystem, client-server design, ECOM, threading and, for all applications, good coding techniques.

To find out more, the first place to start is the Symbian OS Library. In addition, the Resources section of this tutorial provides links to other comprehensive sources of information about Symbian OS.