03.01.2013 Views

Chapter 1

Chapter 1

Chapter 1

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

TBuf helloWorld(_L("hello"));<br />

greetEntity(helloWorld, _L("world!"));<br />

I've used an alternative format for the literals used to initialize descriptors here: _L produces<br />

a TPtrC, which describes the text in the string. So greetEntity() gets called with<br />

TBuf and TPtrC parameters, which suitably match its prototype requirements.<br />

We saw when discussing TDesC how the current data length is always the first machine<br />

word of a concrete descriptor class, allowing the same Length() implementation in all<br />

classes. In TDes and its derived classes, the maximum allowed data length is always the<br />

second machine word, so TDes::MaxLength() is implemented identically for all<br />

modifiable descriptor classes.<br />

The address of the first byte of data therefore varies depending on the concrete type of the<br />

descriptor class: sometimes it's the first byte after the length; sometimes it's the first byte<br />

after the maximum length; sometimes it's contained in a pointer after the length. This is why<br />

TDesC::Ptr()is implemented differently for each descriptor class.<br />

Every other TDesC or TDes function depends only on Ptr(), Length(), and<br />

MaxLength(), so they can be implemented without any dependence on the concrete<br />

descriptor class.<br />

5.2.6 Literals Again<br />

We've now seen two kinds of literal descriptor:<br />

� _LIT, which associates a symbol with a literal value and produces a TLitC, which is<br />

not derived from TDesC<br />

� _L, which produces a TPtrC from a literal value and can be used without a name.<br />

At first sight, _L is more attractive, for precisely the two reasons I mentioned above. It was<br />

the only type of literal supported until Symbian OS v5.0, when _LIT was added. This is now<br />

preferred to using _L in most circumstances: let's see why.<br />

Here's how _L works. It is defined as<br />

#define_L(string) TPtrC((const TText*) string)<br />

So that<br />

const TDesC& helloRef = _L("hello");<br />

It does three things:<br />

� When the program is built, the string, including the trailing NUL, is built into the<br />

program code. We can't avoid the trailing NUL because we're using the C compiler's<br />

usual facilities to build the string.<br />

� When the code is executed, a temporary TPtrC is constructed as an invisible<br />

automatic variable with its pointer set to the address of the first byte of the string and its<br />

length set to five.<br />

� The address of this TPtrC temporary is then assigned to the const TDesC& reference,<br />

helloRef, a fully-fledged automatic variable.<br />

This code works provided either that the reference is only used during the lifetime of the<br />

temporary – that is, during the lifetime of the function – or that the TPtrC pointer and length<br />

are copied if the descriptor is required outside this lifetime. This is usually OK, but you get<br />

the feeling that you're walking on eggshells.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!