Here are some guidelines and examples for translating from C or C++ in other environments to the Symbian OS environment.
· Replace char* data members, variables and function return values with TPtr, TPtrC or HBufC*
· Replace char* parameters to functions with (const TDesC&) or (TDes&)
· Replace char[N] data members and variables with TBuf or TBufC
· Replace const char* with the 'C' versions of the classes
· For allocated memory use HBufC*.
· Use the constructor or Set() to change what a descriptor points to; use the assignment operator to change what its buffer contains.
· Warning: Initialisation and assignment have totally different semantics. This contravenes almost every C++ style guide in existence, but the decision dates back to before most of them existed and now we're stuck with it. The assignment operator does a memory copy.
In the following examples, string represents a read-only character string. buf represents a modifiable buffer for manipulating strings.Data Members and Initialization
Typical C++ For Null-Terminated Strings |
In Psion EPOC32 |
char buf[BUFSIZE]; |
TDes buf; |
// String referenced by a class: const char* iString; iString = ...; |
TPtrC iString; iString.Set( ... ); |
// String managed by a class char * iBuf = ... ; |
HBufC* ipBuf = ... ; |
const char* string = "Hello"; |
TPtrC string( _L( "Hello" ) ); |
const char* string = charArrayZ; |
TPtrC string( charArrayZ ); |
Parameters and values
foo( const char* aString ) |
foo( const TDesC& aString ) |
modify( char * aBuf, int iSize ); |
modify( TDes& aBuf ); |
// Returning allocated memory char* buf = foo() delete [] buf; |
HBufC* pBuf = foo() delete pBuf; |
// Returning ptr to another's mem const char* string = foo(); |
TPtrC string = foo(); |
Operations on strings
strlen( string ); |
string.Length(); |
memset( buf, '\0', BUFSIZE ); |
buf.FillZ( buf.MaxLength() ); |
buf[0] = '\0'; |
buf.Zero(); |
strcpy( buf, "Hello" ); |
buf = _L( "Hello" ); |
sprintf( buf, "%s\n", string ); |
buf.Format( _L("%S\n"), &string); |
strcpy( buf, string1 ); strcat( buf, string2 ); |
buf = string1; buf.Append( string2 ); |
char * iBuf = strdup( string ); |
HBufC* ipBuf = string.AllocL(); |
Notes Descriptors reference chunks of memory of known size. Compared with standard C they replace the common combination of char* plus integer buffer length.
Descriptors combine The data adress [ char* x; ]
The data length [ strlen( x ) ], and, for modifiable buffers:
The buffer size [int xBufferSize; ]
They cope seamlessly with unicode (two-byte) characters. What the classes actually contain:
TDesC (abstract base class for everything) has a length;
TPtrC adds a memory address to TDesC.
TDes (abstract) is a modifiable TDesC, and therefore adds a maximum length to TDesC
TPtr adds a memory address to TDes
TBufC contains a read-only char array of size N
TBuf contains a read-write char array of max size N, plus its current length
HBufC adds an allocated buffer to TDes. The 'C' is misleading; an HBufC is modifiable; just call Des() on it to get a TPtr. You might think of it as similar to a Pascal string, combining length and allocated memory. Use HBufC::New(), NewL() or NewLC() to allocate an empty buffer, or use the function AllocL() on any descriptor to make an allocated copy of its data.