How to use the non-modifiable pointer descriptor - TPtrC

Non-modifiable pointer descriptors are useful for referencing constant strings or data; for example, accessing strings built into ROM resident code, or passing a reference to data in RAM which must not be modified through that reference.

  • For text data, it is usual to construct a TPtrC type and allow the appropriate variant, either a TPtrC8 or a TPtrC16 to be selected at build time.
  • For binary data, an explicit TPtrC8 is used.
  • It is rare to use an explicit TPtrC16.

Constructing a TPtrC

A non-modifiable pointer descriptor can be constructed in a number of ways:

  • any other descriptor.

  • another non-modifiable pointer descriptor.

  • a pointer into memory and specifying the length of the data.

  • a zero terminated string.

The following code fragment constructs a TPtrC to represent the data already represented by any other type of descriptor.

The source descriptor is a literal which is converted to descriptor type.

_LIT(KText,"Hello World!");
...
TBufC<16> buf1(KText);  // buf1 is the existing descriptor
...
TPtrC ptr(buf1);        // data in buf1 now accessible through ptr

The following code fragment constructs a TPtrC to represent the data already represented by another TPtrC.

_LIT(KText,"Hello World!");
...
TBufC<16> buf1(KText);   // buf1 is the existing descriptor
...
TPtrC ptr1(buf1);        // data in buf1 now accessible through ptr1
TPtrC ptr2(ptr1);        // data also accessible through ptr2

Although rarely used (possibly in porting legacy 'C' code), the following code fragment defines a constant "C" style non-Unicode string and then constructs the non-modifiable pointer descriptor for that string. The explicit 8 bit variant is used here. The descriptor is separate from the data it represents.

const TText8* cstr = (TText8*)"Hello World!";
...
TPtrC8 ptr(cstr);
...
ptr.Length();       // The length is 12.
ptr.Ptr();          // The address of the descriptor's data,
                    // i.e. 'C' string.

The following code fragment shows construction from a pointer into memory and a length. The example assumes that both the pointer and the length have valid values:

TUint8*  memptr;
TInt    length;
...
TPtrC8 ptr(memptr,length);

Accessing data

Once a non-modifiable pointer descriptor has been constructed, the functions in the base class, TDesC, are available to access the data.

For example, given a pointer descriptor labelled ptr:#

_LIT(KText,"Hello World!");
...
TBufC<16> buf1(KText);  // buf1 is the existing descriptor
...
TPtrC ptr(buf1);        // data in buf1 now accessible through ptr
...
ptr.Length();           // returns the length of the data (i.e. 12)
Related concepts
Dynamic Buffers