OPXs from the C++ view

Summary: OPXs are extensions to OPL, written in C++, that supply additional commands to the OPL developer.

Contents

1. Introduction

To supply an OPX you need to create at least three files:

These three files have been listed as an example of a working OPX to help you write your own.

In the listings the comments are in red.

2. The CPP file

This is the C++ file that contains the OPX code.

#include "Example.h"     Includes the above header file

#pragma data_seg(".E32_UID") __WINS_UID(0,KUidOpxValue,KUidOpxSystem) 
    #pragma data_seg()
CSystemOpx::CSystemOpx()
    {
      __DECLARE_NAME(_S("CSystemOpx"));
    }
void CSystemOpx::IsReadOnly(OplAPI& aOplAPI)

The OPX procedure

   {
    TPtrC8 file=aOplAPI.PopString8();
    RFs& fs=aOplAPI.DbManager()->FsSession();
    TUint attVal;
    fs.Att(file,attVal);
    aOplAPI.Push(TInt32(attVal & KEntryAttReadOnly ? -1 : 0));
    }

CTlsDataOPXSystem::CTlsDataOPXSystem(OplAPI& aOplAPI) : 
    COpxBase(aOplAPI)    {    __DECLARE_NAME(_S("CTlsDataOPXSystem"));    } CTlsDataOPXSystem* CTlsDataOPXSystem::NewL(OplAPI& aOplAPI)    {    CTlsDataOPXSystem* This=new(ELeave) CTlsDataOPXSystem(aOplAPI); CleanupStack::PushL(This);    This->ConstructL();    CleanupStack::Pop();    return This;    } void CTlsDataOPXSystem::ConstructL()    {    iSystemHandle= new(ELeave) CSystemOpx;    } CTlsDataOPXSystem::~CTlsDataOPXSystem()    {    delete iSystemHandle;    Dll::FreeTls();    } void CTlsDataOPXSystem::RunL(TInt aProcNum)

Runs the OPX procedure

   {
    switch (aProcNum)
         {
    case EIsReadOnly:
           iSystemHandle->IsReadOnly(iOplAPI);
          break;
    default:
           User::Leave(KOplErrOpxProcNotFound);
          }
    }

TBool CTlsDataOPXSystem::CheckVersion(TInt aVersion)

OPX loading interface, to check whether the OPX is a compatible version.
Major version must be <= OPX's version.

   {
    if ((aVersion & 0x0f00)>(KOpxVersion & 0xf00))
       return EFalse;
    else
       return ETrue;
    }

EXPORT_C COpxBase* NewOpxL(OplAPI& aOplAPI)
Creates a COpxBase instance as required by the OPL runtime
This object is to be stored in the OPX's TLS as shown below
   {
   CTlsDataOPXSystem* tls=((CTlsDataOPXSystem*)Dll::Tls());
   if (tls==NULL)
      {
      tls=CTlsDataOPXSystem::NewL(aOplAPI);
      Dll::SetTls(tls);
      }
   return (COpxBase *)tls;
   }

GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
DLL entry point
   {
   return(KErrNone);
   }

3. The C++ header file

The C++ header file defines the public and private classes for the OPX.

#if !defined(__Example_H__)
  #define __Example_H__

#if !defined(__OPXAPI_H__)       These lines include other necessary
  #include <opxapi.h>            header files. Opxapi.h gives
#endif                           access to all functions needed
#if !defined(__E32BASE_H__)      specifically for OPL and OPXs.
  #include <e32base.h>           E32Base provides access to the
#endif                           to the core, EPOC functions.

#define KOpxVersion 0x100        Sets the OPX's version number
                                 which is used in the OXH file

class CSystemOpx :public CBase   Class to keep all the OPX procedures
  {                              in for neatness
public:
  CSystemOpx();
  ~CSystemOpx();
  void IsReadOnly(OplAPI& aOplAPI);
The OPX procedure
  };

The following class is derived from the OPX base class COpxBase and is the main class involved in the OPX where non-const static data can be stored. It provides the thread local storage and the minimum requirements for writing an OPX.

class CTlsDataOPXSystem : public COpxBase
  {
public:
  static CTlsDataOPXSystem* NewL(OplAPI& aOplAPI);
  void ConstructL();
  CTlsDataOPXSystem(OplAPI& aOplAPI);
  ~CTlsDataOPXSystem() ;
  virtual void RunL(TInt aProcNum);
  virtual TBool CheckVersion(Tint aVersion);
  CSystemOpx* iSystemHandle;
private:
  enum TExtensions    The number seventeen is the ordinal that
    {                 corresponds to this function so that it
    EIsReadOnly=17    may be located in the DLL. This number
    };                is also along side the corresponding
  };                  procedure in the OXH header file.

inline CTlsDataOPXSystem* TheTls()
            {return((CTlsDataOPXSystem *)Dll::Tls()); }
inline void SetTheTls(CTlsDataOPXSystem *theTls)
            {DLL::SetTls(theTls); }
#endif 

4. The OPL header file - OXH

DECLARE OPX SYSTEM,&1000025C,$100
    IsReadOnly&:(file$) : 17
END DECLARE

This file is included by the OPL program using INCLUDE "opxhead.oxh", where opxhead.oxh is the name of the header file.

&1000025c is the OPX's unique id and $100 is the OPX's version number.

The number 17 is the ordinal which is necessary in locating this procedure in the System.opx  DLL. The name of the procedure is not important but the & and file$ are important as these tell the OPL translator which data types are passed and returned.

5. Acknowledgements

Symbian is a trademark of Symbian Ltd.

The Symbian Developer Network logo is a trademark of Symbian Ltd.

This paper refers to trademarks of third parties and Symbian recognizes their rights.



Back to opl-dev project homepage

SourceForge.net Logo Symbian logo