Writing Interface Definitions

To use a plug-in, the client of the plug-in framework needs to instantiate an object through the interface definition, use the object and delete the object when the scope of the object usage is complete. Client calls to the interface definition for construction and destruction translate directly through REComSession into loading and unloading of the correct implementation.

The interface definition defines functions that offer services to the clients and enable object instantiation. The object instantiation functions uses the plug-in framework to create an instance of an appropriate implementation, and returns the instance to the client.

A function in the interface definition delegates the object instantiation to a static function REComSession::CreateImplementationL() . The REComSession::CreateImplementationL() is an overloaded function and offers many input parameter options. The appropriate REComSession::CreateImplementationL() function is called for object instantiation. If the client passes input data then this data must be wrapped in a TEComResolverParams object.

  1. Derive an interface definition class from CBase or RHandleBase based class. The class must always declare a private UID member. The following shows an example segment of an interface definition class that derives from CActive.
    class CExampleInterfaceDefinition : public CActive
        {
    public:
        // Wraps ECom object instantiation
        static CExampleInterfaceDefinition* NewL();
         static CExampleInterfaceDefinition* NewL(const TDesC& aMatchString);
        // Wraps ECom object destruction 
        virtual ~CExampleInterfaceDefinition();
        // Interface service 
        virtual void DoMethodL() = 0;
    ...
    private:
        // Instance identifier key or UID.
        TUid iDtor_ID_Key;
        };
  2. Implement the object creation function NewL() for the derived class. Call the appropriate REComSession::CreateImplementationL() function if the implementation is to receive data from the client.
        // The NewL() function accepts client resolution string as input
    inline CExampleInterfaceDefinition* CExampleInterfaceDefinition::NewL(const TDesC& aMatchString)
        {
        const TUid KExampleInterfaceDefinitionUid = {0x10009DC0};
        // The client resolution string is wrapped in TEComResolverParams object for resolution. 
                 TEComResolverParams resolverParams; 
           resolverParams.SetDataType(aMatchString);
           TAny* ptr = REComSession::CreateImplementationL(
              KExampleInterfaceDefinitionUid,
             _FOFF(CExampleInterfaceDefinition,iDtor_ID_Key),
             resolverParams);
    
          return REINTERPRET_CAST <CExampleInterfaceDefinition*>(ptr);
          }

The interface definition needs to define a destructor function to destroy the object after use. The interface destructor notifies the plug-in framework about the object destruction.

The destructor of the interface definition must call the static function REComSession::DestroyedImplementation() to signal the object destruction to plug-in framework. The instance identifier key is passed as a input parameter to REComSession::DestroyedImplementation() to identify the instance.

inline CExampleInterfaceDefinition::~CExampleInterfaceDefinition()
    {
    REComSession::DestroyedImplementation(iDtor_ID_Key);
}

Note: The memory clean-up functionREComSession::FinalClose() should not be invoked inside the destructor, or elsewhere in the interface. For more details refer the topic Cleaning-up Memory.