diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8EB25927-D49E-578F-BD93-294C4EECB7E7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8EB25927-D49E-578F-BD93-294C4EECB7E7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,809 @@ + + + + + +Basic +APIsAccessing APIs and basic functions in kernel-side programs. +

Device drivers, like user-side programs, need to use APIs for basic tasks +such as managing buffers and arrays. However, the EKA2 architecture does not +allow kernel-side programs such as drivers to link and use the User Library +(euser.dll) that provides these APIs to user-side programs. +This means kernel side code cannot use the majority of classes and +functions that are available to user side code.

+

However, some classes are available for use on both the user side and the +kernel side. The first section of this document, Available EUSER functionality, explains what these are. In other cases, +there are alternative Kernel-specific APIs or techniques that you can use. +The second section, Coding +techniques to replace EUSER functionality, describes these.

+

The detailed contents are given below:

+

Contents

+ +
Available EUSER +functionality

This is a list of USER side classes, types and APIs +that can still be used on the kernel side. However, a subset of the class +member functions may not be available.

    +
  • 8-bit descriptors

  • +
  • Arrays

  • +
  • Character representation (TChar)

  • +
  • Basic utility functions and classes

  • +
  • The Package Buffers API

  • +
  • The UID manipulation APIs

  • +
  • Version handling API

  • +
  • TRequestStatus

  • +
  • TIpcArgs

  • +
  • Basic graphic classes

  • +

8-bit descriptors

The +following classes, defined in e32des8.h, can be +used on the kernel side.

For some classes, the kernel side can use +the same member functions that are available to the user side. However, for +other classes, the kernel side is restricted to using a subset of functions; +where this is the case, the functions are listed

+ + + +

Classes available

+

Public member functions that are available to kernel side code

+
+ +

TDesC8

+

TInt operator<(const TDesC8 &aDes) const;

TInt +operator<=(const TDesC8 &aDes) const;

TInt +operator>(const TDesC8 &aDes) const;

TInt operator>=(const +TDesC8 &aDes) const;

TInt operator==(const +TDesC8 &aDes) const;

TInt operator!=(const +TDesC8 &aDes) const;

const TUint8 &operator[](TInt +anIndex) const;

TInt Length() const;

TInt +Size() const;

const TUint8 *Ptr() const;

TInt +Compare(const TDesC8 &aDes) const;

TInt Match(const +TDesC8 &aDes) const;

TInt MatchF(const TDesC8 +&aDes) const;

TInt MatchC(const TDesC8 &aDes) +const;

TInt Locate(TChar aChar) const;

TInt +LocateReverse(TChar aChar) const;

TInt Find(const +TDesC8 &aDes) const;

TInt Find(const TUint8 +*pS,TInt aLenS) const;

TPtrC8 Left(TInt aLength) +const;

TPtrC8 Right(TInt aLength) const;

TPtrC8 +Mid(TInt aPos) const;

TPtrC8 Mid(TInt aPos,TInt +aLength) const;

TInt CompareF(const TDesC8 &aDes) +const;

+
+ +

TDes8

+

TDes8& operator=(const TUint8 *aString);

TDes8& +operator=(const TDesC8 &aDes);

TDes8& operator=(const +TDes8 &aDes);

TInt MaxLength() const;

TInt +MaxSize() const;

const TUint8 &operator[](TInt +anIndex) const;

TUint8 &operator[](TInt anIndex);

TDes8 +&operator+=(const TDesC8 &aDes);

void Zero();

void +SetLength(TInt aLength);

void SetMax();

void +Copy(const TDesC8 &aDes);

void Copy(const TUint8 +*aBuf,TInt aLength);

void Copy(const TUint8 *aString);

void +Copy(const TDesC16 &aDes);

void Append(TChar +aChar);

void Append(const TDesC8 &aDes);

void +Append(const TDesC16 &aDes);

void Append(const +TUint8 *aBuf,TInt aLength);

void Fill(TChar aChar);

void +Fill(TChar aChar,TInt aLength);

void FillZ();

void +FillZ(TInt aLength);

void Num(TInt64 aVal);

void +Num(TUint64 aVal, TRadix aRadix);

void NumFixedWidth(TUint +aVal,TRadix aRadix,TInt aWidth);

void +AppendNum(TInt64 aVal);

void AppendNum(TUint64 +aVal, TRadix aRadix);

void AppendNumFixedWidth(TUint +aVal,TRadix aRadix,TInt aWidth);

+
+ +

TPtrC8

+

Same as for user side code.

+
+ +

TPtr8

+

Same as for user side code.

+
+ +

TBufC8

+

Same as for user side code.

+
+ +

TBuf8

+

Same as for user side code.

+
+ +

TDes8Overflow

+

Same as for user side code.

+
+ +

TLitC8

+

Same as for user side code.

+
+ + +

Arrays

The +following classes, defined in e32cmn.h, can be +used on the kernel side.

For some classes, the kernel side can use +the same member functions that are available to the user side. However, for +other classes, the kernel side is restricted to using a subset of functions; +where this is the case, the functions are listed

+ + + +

Classes available

+

Public member functions that are available to kernel side code

+
+ +

RArray <class T>

+

RArray();

RArray(TInt aGranularity);

RArray(TInt +aGranularity, TInt aKeyOffset);

RArray(TInt aMinGrowBy, +TInt aKeyOffset, TInt aFactor);

void +Close(); inline TInt Count() const;

const T& +operator[](TInt anIndex) const;

T& operator[](TInt +anIndex);

TInt Append(const T& anEntry);

TInt +Insert(const T& anEntry, TInt aPos);

void Remove(TInt +anIndex);

void Compress();

void +Reset();

TInt Find(const T& anEntry) const;

TInt +Find(const T& anEntry, TIdentityRelation<T> anIdentity) +const;

TInt FindInSignedKeyOrder(const T& anEntry) + const;

TInt FindInUnsignedKeyOrder(const +T& anEntry) const;

TInt +FindInOrder(const T& anEntry, TLinearOrder<T> +anOrder) const;

TInt FindInSignedKeyOrder(const +T& anEntry, TInt& anIndex) const;

TInt +FindInUnsignedKeyOrder(const T& anEntry, TInt& +anIndex) const;

TInt FindInOrder(const T& anEntry, +TInt& anIndex, TLinearOrder<T> anOrder) const;

TInt +SpecificFindInSignedKeyOrder(const T& anEntry, TInt +aMode) const;

TInt SpecificFindInUnsignedKeyOrder(const +T& anEntry, TInt aMode) const;

TInt +SpecificFindInOrder(const T& anEntry, TLinearOrder<T> +anOrder, TInt aMode) const;

TInt SpecificFindInSignedKeyOrder(const +T& anEntry, TInt& anIndex, TInt aMode) const;

TInt +SpecificFindInUnsignedKeyOrder(const T& anEntry, +TInt& anIndex, TInt aMode) const;

TInt SpecificFindInOrder(const +T& anEntry, TInt& anIndex, TLinearOrder<T> +anOrder, TInt aMode) const;

TInt InsertInSignedKeyOrder(const +T& anEntry);

TInt InsertInUnsignedKeyOrder(const +T& anEntry);

TInt InsertInOrder(const +T& anEntry, TLinearOrder<T> anOrder);

TInt +InsertInSignedKeyOrderAllowRepeats(const T& anEntry);

TInt +InsertInUnsignedKeyOrderAllowRepeats(const T& anEntry);

TInt +InsertInOrderAllowRepeats(const T& anEntry, TLinearOrder<T> +anOrder);

+
+ +

RArray <TInt>

+

RArray();

RArray(TInt aGranularity);

RArray(TInt +aMinGrowBy, TInt aFactor);

void Close();

TInt +Count() const;

const TInt& operator[](TInt +anIndex) const;

TInt& operator[](TInt anIndex);

TInt +Append(TInt anEntry);

TInt Insert(TInt anEntry, +TInt aPos);

void Remove(TInt anIndex);

void +Compress();

void Reset();

TInt +Find(TInt anEntry) const;

TInt FindInOrder(TInt +anEntry) const;

TInt FindInOrder(TInt anEntry, +TInt& anIndex) const;

TInt +SpecificFindInOrder(TInt anEntry, TInt aMode) const;

TInt +SpecificFindInOrder(TInt anEntry, TInt& anIndex, +TInt aMode) const;

TInt InsertInOrder(TInt anEntry);

TInt +InsertInOrderAllowRepeats(TInt anEntry);

+
+ +

RArray <TUint>

+

RArray();

RArray(TInt aGranularity);

RArray(TInt +aMinGrowBy, TInt aFactor);

void Close();

TInt +Count() const;

const TUint& operator[](TInt +anIndex) const;

TUint& operator[](TInt anIndex);

TInt +Append(TUint anEntry);

TInt Insert(TUint anEntry, +TInt aPos);

void Remove(TInt anIndex);

void +Compress();

void Reset();

TInt +Find(TUint anEntry) const;

TInt FindInOrder(TUint +anEntry) const;

TInt FindInOrder(TUint anEntry, +TInt& anIndex) const;

TInt +SpecificFindInOrder(TUint anEntry, TInt aMode) const;

TInt +SpecificFindInOrder(TUint anEntry, TInt& anIndex, +TInt aMode) const;

TInt InsertInOrder(TUint anEntry);

TInt +InsertInOrderAllowRepeats(TUint anEntry);

+
+ +

RPointerArray <class T>

+

RPointerArray();

RPointerArray(TInt +aGranularity);

RPointerArray(TInt aMinGrowBy, TInt +aFactor);

void Close();

TInt +Count() const;

T* const& operator[](TInt anIndex) +const;

T*& operator[](TInt anIndex);

TInt +Append(const T* anEntry);

TInt Insert(const T* +anEntry, TInt aPos);

void Remove(TInt anIndex);

void +Compress();

void Reset();

void +ResetAndDestroy();

TInt Find(const T* anEntry) +const;

TInt Find(const T* anEntry, TIdentityRelation<T> + anIdentity) const;

TInt FindInAddressOrder(const +T* anEntry) const;

TInt FindInOrder(const T* anEntry, +TLinearOrder<T> anOrder) const;

TInt +FindInAddressOrder(const T* anEntry, TInt& anIndex) +const;

TInt FindInOrder(const T* anEntry, TInt& +anIndex, TLinearOrder<T> anOrder) const;

TInt +SpecificFindInAddressOrder(const T* anEntry, TInt aMode) +const;);

TInt SpecificFindInOrder(const T* anEntry, + TLinearOrder<T> anOrder, TInt aMode) const;

TInt +SpecificFindInAddressOrder(const T* anEntry, TInt& +anIndex, TInt aMode) const;

TInt SpecificFindInOrder(const +T* anEntry, TInt& anIndex, TLinearOrder<T> anOrder, +TInt aMode) const;

TInt InsertInAddressOrder(const +T* anEntry);

TInt InsertInOrder(const T* anEntry, + TLinearOrder<T> anOrder);

TInt +InsertInAddressOrderAllowRepeats(const T* anEntry);

TInt +InsertInOrderAllowRepeats(const T* anEntry, TLinearOrder<T> +anOrder);

+
+ +

TIdentityRelation <class T>

+

Same as for user side code.

+
+ +

TLinearOrder <class T>

+

Same as for user side code.

+
+ + +

Character representation

The +following class, defined in e32cmn.h, can be used +on the kernel side.

For some classes, the kernel side can use the +same member functions that are available to the user side. However, for other +classes, the kernel side is restricted to using a subset of functions; where +this is the case, the functions are listed

+ + + +

Classes available

+

Public member functions that are available to kernel side code

+
+ +

TChar

+

TChar();

TChar(TUint aChar);

TChar& +operator-=(TUint aChar);

TChar& operator+=(TUint +aChar);

TChar operator-(TUint aChar);

TChar +operator+(TUint aChar);

operator TUint() const;

+
+ + +

Basic utility +functions and classes

The following global utility functions and +classes, defined in e32cmn.h, can be used on the +kernel side.

+ + + +

TRefByValue

+
+ +

TInt Lim(TInt aVal,TUint aLimit);

+
+ +

TInt LimX(TInt aVal,TUint aLimit);

+
+ +

template <class T> T Min(T aLeft,T aRight);

+
+ +

template <class T> T Min(T aLeft,TUint + aRight);

+
+ +

template <class T> T Max(T aLeft,T aRight);

+
+ +

template <class T> T Max(T aLeft,TUint + aRight);

+
+ +

template <class T> T Abs(T aVal);

+
+ +

template <class T> TBool Rng(T aMin,T aVal,T + aMax);

+
+ +

template <class T,class S> T* PtrAdd(T* aPtr,S + aVal);

+
+ +

template <class T,class S> T* PtrSub(T* aPtr,S + aVal);

+
+ +

template <class T> T Align2(T aValue);

+
+ +

template <class T> T Align4(T aValue);

+
+ + +

The Package +Buffers API

The package buffers API, represented by classes defined +in e32cmn.h, can be used on the kernel side.

+ + + +

TPckgBuf

+
+ +

TPckgC

+
+ +

TPckg

+
+ + +

The UID manipulation +APIs

The UID manipulation APIs, represented by classes defined +in e32cmn.h can be used on the kernel side. However, +only a subset of functions are available. See the detailed notes in +the following table.

+ + + +

TUid

+

Only the two inline functions can be used:

    +
  • TUid::Uid

  • +
  • TUid::Null()

  • +
+
+ +

TUidType

+

None of the member functions can be used; however, the iUid data +member is declared as public on the kernel side.

+
+ +

TUidName

+

This will only ever be an 8-bit type descriptor.

+
+ + +

Version handling +API

The version handling API, represented by the TVersion class +defined in e32cmn.h can be used on the kernel side.

TRequestStatus

The TRequestStatus class +representing the completion status of an asynchronous request, and defined +in e32cmn.h can be used on the kernel side.

TIpcArgs

The TIpcArgs class, which is part of the Version2 client/server APIs, +and defined in e32cmn.h, can be used on the kernel side. +However, the Set() and Type() member functions +that take 16-bit descriptors are not available.

Basic +graphic classes

The basic graphic classes TPoint and TSize are +defined on the kernel side. However, only the public data members are defined +- the member functions are not defined, and are not available for use.

+
Coding techniques +to replace EUSER functionality
    +
  • Buffers: replacing HBufC8 with HBuf

  • +
  • Buffers: replacing HBufC8 with C style pointers

  • +
  • Handling 16-bit data items

  • +
  • Replacing CBase with DBase

  • +
  • Replacing User::QueryVersionSupported() with Kern::QueryVersionSupported()

  • +

Buffers: replacing +HBufC8 with HBuf

In EKA2, the heap descriptor buffer, HBufC8 is +not available. However, the kernel side defines and implements an equivalent +(kernel) heap descriptor buffer: HBuf8. HBuf8 is +behaves in a similar way to HBufC8, so nearly all of your +code can be reused, but note the following points:

    +
  • If your code uses the +typedef HBufC, then you need to change it to HBuf.

  • +
  • On the kernel side, +there is no explicit support for 16-bit buffers, which means that there is +no class called HBuf16. In practice, this means that, HBuf is +always the same as HBuf8.

  • +
  • Unlike HBufC8, HBuf8 is +a modifiable type descriptor. It has TDes8 in its derivation +hierarchy, and this means that you can manipulate the descriptor's data (using +the TDes8 member functions).

  • +
  • The number of functions +available to create an HBuf8 object is more limited than +for HBufC8 - there are only three variants - although in +practice this is not a problem:

      +
    • HBuf8::New(TInt +aMaxLength) to allocate a heap descriptor buffer (on the kernel heap) +and set its length to zero; this behaves the same as the user side HBufC8::New(TInt +aMaxLength)

    • +
    • HBuf8::New(const +TDesC8& aDes) to allocate a heap descriptor buffer (on the kernel +heap) and initialise it by copying an existing descriptor's data into it.

    • +
    • HBuf8::ReAlloc(TInt +aNewMax) to re-allocate (i.e. to resize) a heap descriptor buffer +(on the kernel heap); this behaves the same as the user side HBufC8::New(TInt +aMaxLength)

    • +
  • +
  • There are no "leaving" +variants of these functions - if you have NewL(), NewLC(), and other "leaving" +variants, then you will need to change your code to explicitly check the return +code to make sure that the creation, or the reallocation of the heap descriptor +buffer has worked.

  • +
  • As the descriptor is +modifiable, there is no need for, and there is no equivalent of the function HBufC8::Des(); +you just use the base class TDes8 functions.

  • +
  • If your code uses the +assignment operators (i.e. the = operator), you don't need +to change your code; the compiler will use the operators implemented in the TDes8 base +class, which will do the right thing.

  • +
  • The descriptor function TDesC8::Alloc() is +no longer available on the kernel side, so you cannot create a heap descriptor +buffer from a general descriptor.

  • +

The following code fragments show code that is approximately equivalent +between EKA1 and EKA2. The fragments are a little artificial, and make assumptions +that would not necessarily be made in real code, but nevertheless still show +the essential differences.

+ + + +

EKA1

+

EKA2

+
+ +

This is a function that allocates a heap descriptor buffer (HBufC8), +puts data into it, changes its size, replaces the data, deletes a part of +the data, and then deletes it.

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +void X::FunctionL() + { + // Create a buffer big enough to contain + // the text "abcdef". + // This uses the "leaving" variant, and leaves + // if there is insufficient memory. + HBufC8* pBuf = HBufC8::NewL(KTxSmall().Length()); + + // Copy the text "abcdedf" into it + *pBUf = KTxSmall; + + // Make the buffer bigger... + // ... and check that it worked OK + // Note that we are using the non-leaving version. + // We could use the leaving version, but we would + // need to handle the cleanup of pBuf + HBuf8* pNewBuf = pBuf->ReAlloc(KTxBig().Length());; + + if (pNewBuf) + { + pBuf = pNewBuf; + } + else + { + delete pBuf; + User::Leave(KErrNoMemory); + } + + // Replace content of the descriptor with + // the text "ghijkl......" + *pBuf = KTxBig; + + // Need to use the Des() function to create + // a modifiable descriptor before we can make + // changes to the text in the descriptor. + TPtr8 pDesPtr; + pDesPtr = pBuf->Des(); + + // Delete the 1st two characters. + PDesPtr.Delete(0,2) + + delete pBUf; + + return; + }
+

A similar function, but it uses HBuf8 instead.

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +TInt X::Function() + { + // Create a buffer big enough to contain + // the text "abcdef", and copy the text + // from its source into the buffer. + // + // You need to check explicitly that this + // has worked. + HBuf8* pBuf = HBuf8::New(KTxSmall); + if (!pBuf) + { + return KErrNoMemory; + } + + // Make the buffer bigger... + // .. and check that it worked OK + HBuf8* pNewBuf = pBuf->ReAlloc(KTxBig().Length()); + + if (pNewBuf) + { + pBuf = pNewBuf; + } + else + { + delete pBuf; + return KErrNoMemory; + } + + // You can still use the =operator to replace + // the content of the heap descriptor ! + // Replace content with + // the text "ghijkl......" + *pBuf = KTxBig; + + + // Can now use use the TDes8 functions + // directly. + // This deletes the 1st two characters. + pBuf->Delete(0,2); + + // delete the heap descriptor + delete pBUf; + + return KErrNone; + }
+
+ +

A small code fragment that uses TDesC8::Alloc() to +create an HBufC8 heap descriptor buffer from an existing +descriptor.

HBufC8* X::Function(const TDesC8& aDes) + { + // Returns NULL if creation + // of the heap descriptor buffer fails. + + return aDes.Alloc(); + }

or possibly:

HBufC8* X::FunctionL(const TDesC8& aDes) + { + // Leaves if creation of the heap + // descriptor buffer fails, otherwise it + // returns a valid pointer. + + return(aDes.AllocL()); + }
+

An equivalent code fragment that creates an HBuf8 heap +descriptor buffer.

HBuf8* X::Function(const TDesC8& aDes) + { + // Returns NULL if creation + // of the heap descriptor buffer fails. + + return (HBuf8::New(aDes)); + }
+
+ + +

Buffers: replacing +HBufC8 with C style pointers

Instead of replacing HBufC8 with HBuf, +it may be more suitable to replace your heap descriptor buffers with C style +pointers - effectively managing your buffers in open code or as part of the +implementation of your own purpose written classes.

You allocate memory +from the kernel heap using Kern::Alloc() or Kern::AllocZ() and +track the pointers to that memory. The following code fragments show how the +use of HBufC8 translates to the direct use of these functions.

Although +the EKA2 code here uses memcpy(), and memmove(), +you will also find the functions memclr(), memset(), wordmove() and memcompare() useful in your code.

+ + + +

EKA1

+

EKA2

+
+ +

This is a function that allocates a heap descriptor buffer (HBufC8), +puts data into it, changes its size, replaces the data, deletes a part of +the data, and then deletes the whole buffer.

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +void X::FunctionL() + { + // Create a buffer big enough to contain + // the text "abcdef". + // This uses the "leaving" variant, and leaves + // if there is insufficient memory. + HBufC8* pBuf = HBufC8::NewL(KTxSmall().Length()); + + // Copy the text "abcdedf" into it + *pBUf = KTxSmall; + + // Make the buffer bigger... + // ... and check that it worked OK + // Note that we are using the non-leaving version. + // We could use the leaving version, but we would + // need to handle the cleanup of pBuf + HBuf8* pNewBuf = pBuf->ReAlloc(KTxBig().Length());; + + if (pNewBuf) + { + pBuf = pNewBuf; + } + else + { + delete pBuf; + User::Leave(KErrNoMemory); + } + + // Replace content of the descriptor with + // the text "ghijkl......" + *pBuf = KTxBig; + + // Need to use the Des() function to create + // a modifiable descriptor before we can make + // changes to the text in the descriptor. + TPtr8 pDesPtr; + pDesPtr = pBuf->Des(); + + // Delete the 1st two characters. + PDesPtr.Delete(0,2) + + delete pBUf; + + return; + }
+

A similar function, but allocates memory on the kernel heap explicitly, +and manages its own pointers instead. Note the use of the nanokernel utility +function: memcpy(), and memmove()

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +TInt X::Function() + { + // Create a buffer big enough to contain + // the text "abcdef", and copy the text + // from its source into the buffer. + // + // Steps. + // 1. work out the size of buffer needed + // 2. Get the buffer. + // 3. Copy the source. + + TInt lengthInBuffer = 0; + + // 1. + TInt Smallsize; + SmallSize = KTxSmall().Length(); + lengthInBuffer = SmallSize; + + // 2. + TUint8* pBuf; + pBuf = Kern::Alloc(SmallSize); + if (!pBuf) + { + return KErrNoMemory; + } + + // 3. + memcpy(pBuf,KTxSmall().Ptr(),SmallSize)); + + + // Make the buffer bigger. + // If it works ok, then copy the data + // to the new buffer, delete the old buffer + TInt BiggerSize; + TUint8* pNewBuf; + + BiggerSize = KTxBig().Length(); + pNewBuf = Kern::Alloc(BiggerSize); + if (pNewBuf) + { + memcpy(pNewBuf, pBuf, SmallSize); + Kern::Free(pBuf); + pBuf = pNewBuf; + } + else + { + Kern::Free(pBuf); + return KErrNoMemory; + } + lengthInBuffer = BiggerSize; + + // Replace content with + // the text "ghijkl......" + memcpy(pNewBuf, KTxBig().Ptr(), BiggerSize); + + + // Delete 1st two characters + memmove(pNewBuf, pNewBuf+2, lengthInBuffer; + lengthInBuffer -= 2; + + Kern::Free(pBuf); + + return KErrNone; + }
+
+ + +

Handling 16-bit +data items

If you need to handle 16-bit items on the kernel side, +then you can still use 8-bit heap descriptor buffers. You just need to be +aware that the data is 16 bit and cast accordingly. The following code fragments +are simplistic, but show you the basic idea.

+ + + +

EKA1

+

EKA2

+
+ +

This is a function which is passed a 16-bit descriptor containing +16-bit wide characters.

void X::FunctionL(const TDes16& aDes) + { + HBuf16* pBuf = aDes.AllocL(); + + TInt noOfCharacters; + TUint16* pointerToData; + + noOfCharacters = pBuf->Length(); + pointerToData = pBuf->Ptr(); + + ... + }
+

This is a similar function which is also passed 16-bit wide characters. +The function needs slight changes as it can only receive data through an 8-bit +descriptor.

TInt X::Function(const TDes8& aDes) + { + HBuf8* pBuf = HBuf8::New(aDes); + if (!pBuf) + { + return KErrNoMemory; + } + + TInt noOfCharacters; + TUint16* pointerToData; + + noOfCharacters = ((pBuf->Length()) >> 1); + pointerToData = (TUint16*)(pBuf->Ptr()); + + ... + + return KErrNone; + }
+
+ + +

Replacing CBase +with DBase

The DBase class is the kernel-side +equivalent of the user-side CBase class. It provides zero-filling +of memory prior to object construction and a virtual destructor in a similar +way to CBase.

If you have a class derived from CBase, +then all you need to do is:

    +
  • change your class definition +so that it is derived from DBase.

  • +
  • Remember to include +the klib.h header file.

  • +

you should not need to do anything else.

One additional feature +provided by DBase that is not available in CBase is +the function DBase::AsyncDelete(). This allows you to delete +an instance of a DBase derived class asynchronously, and +is useful if you need to delete a DBase derived object +in time-critical code.

Internally, asynchronous deletion works by +placing the object to be deleted onto a queue, and then triggering a DFC, +which runs in the context of the supervisor thread. This means that only a +small amount of code is executed by your (the calling) thread, and the actual +deletion is done by the supervisor thread.

Its use is straightforward.

class DMyObject : public DBase + { + ... + } DMyObject pPtr; + ... + pPtr = new DMyObject; + ... + pPtr->AsyncDelete(); + ...

Replacing +User::QueryVersionSupported() with Kern::QueryVersionSupported()

User::QueryVersionSupported() is +replaced by Kern::QueryVersionSupported() on the kernel +side.

The parameters passed to these functions are the same, both +in type and meaning. The behaviour of both functions is also the same. This +means that all you need to do is replace User:: with Kern:: in +your code.

+
\ No newline at end of file