diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/PDK/Source/GUID-50E6EEB5-45D2-5B95-BDEA-5615F586DA9C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/PDK/Source/GUID-50E6EEB5-45D2-5B95-BDEA-5615F586DA9C.dita Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,276 @@ + + + + + +Using +Extended InterfacesFramework developers define and publish extension interfaces to +the existing interfaces used in the framework. Once an interface extension +is published by the framework developer, plug-in developers implement the +extension if required. + + +Identify the published instantiation and extended interface UIDs and +header files of the framework. + + +Create a new +project file (.mmp) with targettype variable +set as PLUGIN3. Allocate UIDs for the the plug-in implementations and plug-in +DLL (UID3) as shown in the code snippet below. +TARGET cimplementationclass.dll +TARGETTYPE PLUGIN3 +CAPABILITY All -TCB + +// PLUGIN3 recognition UID followed by the UID for this dll +UID 0x10009D93 0x10009E37 +VENDORID 0x70000001 + +SOURCEPATH ../src +SOURCE cimplementationclass.cpp + +USERINCLUDE ../src +SYSTEMINCLUDE /epoc32/include + +START RESOURCE cimplementationclass.rss +TARGET cimplementationclass.rsc +END + +LIBRARY euser.lib +LIBRARY ecom.lib + + + +Create a new resource file (.rss) of format +version 3. +CImplementationClass.rss +#include <ecom/registryinfov3.rh> + +RESOURCE REGISTRY_INFO theInfo + { + resource_format_version = RESOURCE_FORMAT_VERSION_3; + dll_uid = 0x10009E37; + interfaces = + { + INTERFACE_INFO + { + instantiation_interface_uid = 0x10009DBB; + implementations = + { + IMPLEMENTATION_INFO + { + info_format = IMPLEMENTATION_INFO_RECORD_TYPE1; + implementation_uid = 0x10009E38; + version_no = 1; + display_name = "Extended Interface Example"; + default_data = {"Extended Interface Example||up to 255 chars", "Max. two strings allowed"}; + opaque_data = {"up to 255 chars", “max. 2 strings allowed”}; + extended_interfaces = {0x10009E44, 0x10009E45}; + flags = FLAG_ROM_ONLY; + } + }; + } + }; + } + + + +Implement the interfaces in the plug-in implementation source files. +Implementing an interface extension in a plug-in implementation can +be done in either of the two ways: + + + Inheritance: The instantiation interface object is also of the type +of the extended interface object. When a user wants to instantiate the extended +interface object, the implementation simply returns a re-cast of the instantiation +interface object. +The example below shows implementing an interface extension using inheritance. +//Implementing an interface extension using multiple inheritance +class CImplementationClass : public CExampleInterface, public MExampleInterfaceExtended +{ + +public: + static CImplementationClass* NewL(); + static TAny* GetExtendedInterfaceL(TAny* aInstantiationInterface,const TUid& aExtendedInterfaceUid,TUint32& aBitFlags,TAny*& aReleaseObject); + static void ReleaseExtendedInterface(TAny* aExtendedInterface, const TUid& aExtendedInterfaceUid); + + ~ CImplementationClass() {} + virtual void DoMethodL(); // from original interface + virtual void DoMethodExtended(); //from MExampleInterfaceExtended +private: + CImplementationClass() {} +}; + + + + + Realizing the extended interface as separate class and objects. When +users fetch the extended interface object, the implementation allocates a +new object. +The example below shows implementing an interface extension using realisation. +// Implementing an interface extension using realization + +class CImplementationClassExtended : public CBase, public MExampleInterfaceExtended2 +{ +public: + static CImplementationClassExtended* NewL(); + ~ CImplementationClassExtended() {} + virtual void DoMethodExtended2(); //from MExampleInterfaceExtended2 +private: + CImplementationClassExtended() {} +}; + + + + + +Implement REComSession::CreateImplementationL(),REComSession::GetExtendedInterfaceL(),REComSession::ManuallyReleaseExtendedInterfaceL() functions of the instantiation interface. +TAny* CImplementationClass::GetExtendedInterfaceL(TAny* aInstantiationInterface, +const TUid& aExtendedInterfaceUid, +TUint32& aBitFlags, +TAny*& aReleaseObject) + { + TAny* ret = NULL; + aBitFlags &= ~KReleaseRequiredMask; // clear release flag + switch (aExtendedInterfaceUid.iUid) + { + case 0x10009E44: + { + // release not required, so do not modify aBitFlags. + // re-cast Instantiation object as Extended Interface object + ret = static_cast<MExampleInterfaceExtended *> (static_cast<CImplementationClass *>(aObject)); + break; + } + case 0x10009E45: + { + CImplementationClassExtended *classExt = CImplementationClassExtended::NewL(); + aReleaseObject = classExt; + aBitFlags |= KReleaseRequiredMask; // Indicate release is required + // Multiple inheritance involved – Cbase and the M class. Must use + // either dynamic_cast or static_cast to add offset to the base pointer + ret = static_cast<MExampleInterfaceExtended2*>(classExt); + break; + } + } + return ret; + } + +The plug-in framework releases the extended interface object when the +user destroys the instantiation interface object. Alternatively, if the framework +wants to release the extended interface earlier, they can call the REComSession::ManuallyReleaseExtendedInterfaceL() +void CImplementationClass::ReleaseExtendedInterface(TAny* aExtendedInterface, const TUid& aExtendedInterfaceUid) + { + switch (aExtendedInterfaceUid.iUid) + { + case 0x10009E45: + { + // this Extended Interface object require release. + CImplementationClassExtended* classExt = static_cast<CImplementationClassExtended*>(aReleaseObject); + delete classExt; + break; + } + } + } + +The aInstanceKey parameter is returned by REComSession::CreateImplementationL(). +It identifies the instantiation interface object instance. The aExtendedInterfaceUid +parameter identifies the extended interface required. + + +Export the instantiation functions into a TImplementationProxy3 table. +const TImplementationProxy3 KImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY3(0x10009E38, CImplementationClass::NewL, CImplementationClass::GetExtendedInterfaceL,CImplementationClass::ReleaseExtenedInterface) + }; + +EXPORT_C const TImplementationProxy3* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(KImplementationTable) / sizeof(TImplementationProxy3); + return KImplementationTable; + } + + + + +Export the release functions into a TImplementationProxy3 table. +void CImplementationClass::ReleaseExtendedInterface(TAny* aExtendedInterface, const TUid& aExtendedInterfaceUid) + { + switch (aExtendedInterfaceUid.iUid) + { + case 0x10009E45: + { + // this Extended Interface object require release. + CImplementationClassExtended* classExt = static_cast<CImplementationClassExtended*>(aReleaseObject); + delete classExt; + break; + } + } + } + + + + +

To instantiate and use an extended interface, the plug-in user +must:

    +
  • Identify plug-ins that +support the desired interface extensions using REComSession::ListImplementationsL().

    IMPORT_C static void ListImplementationsL(TUid aInterfaceUid, +RExtendedInterfacesArray& aExtendedInterfaces, + const TEComResolverParams& aResolutionParameters, + RImplInfoPtrArray& aImplInfoArray); +

    The “aInterfaceUid” parameter specifies the instantiation +interface. All of the implementations returned in “aImplInfoArray” support +all the extensions listed in the “aExtendedInterfaces” parameter.

  • +
  • Select one from the +array and create an instantiation interface object.

  • +
  • Call REComSession::GetExtendedInterfaceL() API +to get an extended interface object.

    IMPORT_C static TAny* GetExtenedInterfaceL(const TUid& aInstanceKey, +const TUid& aExtendedInterfaceUid); +

    The aInstanceKey parameter identifies the instantiation interface +object returned by REComSession::CreateImplementationL().

  • +

The example code depicts the above steps:

+const TUid KExampleInterfaceUid = {0x10009DBB}; // the Instantiation Interface +const TUid KExtendedInterfaceUid1 = {0x10009E44}; +const TUid KExtendedInterfaceUid2 = {0x10009E45}; + +// Set up extended interfaces UID list which form part of the resolution criteria. +RArray<TUid> extendedInterfaces; +CleanupClosePushL(extendedInterfaces); +extendedInterfaces.AppendL(KExtendedInterfaceUid1); +extendedInterfaces.AppendL(KExtendedInterfaceUid2); + +// set up resolve parameter +_LIT8(KExampleImplementationData,"Extended Interface Example"); +TEComResolverParams ResolverParams; +ResolverParams.SetDataType(KExampleImplementationData()); +ResolverParams.SetGenericMatch(ETrue); + +TUid instanceKey; +CExampleInterface* instantiateIf = static_cast<CExampleInterface*>( + REComSession::CreateImplementationL(KExampleInterfaceUid, + extendedInterfaces, + instanceKey, + ResolverParams) ); +CleanupStack::PopAndDestroy(&extendedInterfaces); + +CleanupStack::PushL(instantiateIf); +// May want to TRAP here if KErrNotSupported is handled, i.e. extension optional +MExampleInterfaceExtended2* ext2 = static_cast<MExampleInterfaceExtended2*>( + REComSession::GetExtendedInterfaceL(instanceKey, KExtendedInterfaceUid2)); + +instantiateIf->DoMethodL(); // access old interface function +ext2->DoMethodExtended2(); // access extension function + +// Calling ManuallyReleaseExtendedInterface is optional. Do this +// if want to release extended object early. +REComSession::ManuallyReleaseExtendedInterface(instanceKey,KExtendedInterfaceUid2); + +REComSession::DestroyedImplementation(instanceKey); +CleanupStack::PopAndDestroy(instantiateIf); +
+
\ No newline at end of file