Symbian OS Explained - Effective C++ Programming For Smartphones (2005) (779885), страница 52
Текст из файла (страница 52)
Don’t worry too much about this ECOMinternal housekeeping, which initializes iDtor_ID_Key so ECOM canlater identify the object for cleanup. CreateImplementationL()returns a TAny* which must be re-cast to the interface pointer beforereturning it to the caller. There are a number of other overloads ofREComSession::CreateImplementationL(), which you’ll finddocumented in detail in your preferred SDK (from Symbian OS v7.0onwards).The second NewL() factory method takes a cue parameter, which itpasses to the default ECOM resolver. The resolver uses it to determine theconcrete instance of the implementation to be instantiated, by matchingthe cue against the default_data attributes for registered implementations of that interface.
I’ll discuss the role of the default resolver andECOM resource files in more detail later.// interface_uid for CCryptoInterfaceconst TUid KCCryptoInterfaceUid = {0x10008EE0};3Implementations are identified by their implementation_uid attribute, which isdeclared in the resource file associated with the plug-in DLL, as I’ll discuss later in thechapter.4The _FOFF macro is defined as follows in e32def.h:#define _FOFF(c,f) ((TInt)(&((c *)0)->f))It returns the offset in bytes of a member variable f of class cFACTORY METHODS239EXPORT_C CCryptoInterface* CCryptoInterface::NewL(const TDesC8& aCue){// Resolution using the default ECOM resolverTEComResolverParams resolverParams;resolverParams.SetDataType(aCue);// Allows wildcards in the string matchresolverParams.SetWildcardMatch(ETrue);TAny* cryptoInterface =REComSession::CreateImplementationL(KCCryptoInterfaceUid,_FOFF(CCryptoInterface, iDtor_ID_Key), NULL,resolverParams));return (reinterpret_cast<CCryptoInterface*>(cryptoInterface));}Besides the TEComResolverParams object, which encapsulates theresolver cue, other parameters passed to REComSession::CreateImplementationL() include the UID of the requested interface and theoffset of iDtor_ID_Key as discussed previously.
The third parameter,NULL in the example above, can be used to pass data to the initializationmethod of the concrete class. If CreateImplementationL() cannotfind an appropriate interface implementation for the cue given, it leaveswith KErrNotFound.By calling NewL(), an interface client instantiates an object whichimplements that interface. The implementation type is either determinedby the cue passed into NewL() or is the default type. Because the calleruses the interface to perform instantiation, it does not need informationabout the class that actually implements that interface. However, REComSession does provide a function, ListImplementationsL(), whichreturns information about all the implementations of a given interface inan object of type RImplInfoPtrArray.
This can be used to provideinterface clients with a list of every implementation class available. I’llillustrate how a client might use this function at the end of this chapter.EXPORT_C void CCryptoInterface::ListImplementationsL(RImplInfoPtrArray&aImplInfoArray){REComSession::ListImplementationsL(KCCryptoInterfaceUid,aImplInfoArray);}The CCryptoInterface class also defines a virtual destructor, whichcalls the ECOM framework, passing iDtor_ID_Key to identify theobject.
This enables ECOM to perform reference counting and cleanup asnecessary. Subclasses will inherit this destructor code, which C++ callsafter the destructor of the derived class.240ECOMEXPORT_C CCryptoInterface::∼CCryptoInterface(){// Notify ECOM that this object is being deletedREComSession::DestroyedImplementation(iDtor_ID_Key);}14.4Implementing an ECOM InterfaceHaving discussed CCryptoInterface, let’s move on to consider howit is implemented. Concrete classes must be defined in an ECOM plugin DLL, which is built with targettype ECOMIIC (which stands for”ECOM Interface Implementation Collection”).
Here’s the .mmp file forthe example plug-in DLL:// ECryptoExample.mmpTARGET ECryptoExample.dllTARGETTYPE ECOMIIC// UID2 = ECOM plug-in DLL recognition, UID3 = unique UID for this DLLUID 0x10009D8D 0x10009EE1SOURCEPATH .SOURCE // ... Omitted for clarityUSERINCLUDE // ... Omitted for claritySYSTEMINCLUDE \epoc32\include \epoc32\include\ecomRESOURCE 10009EE1.RSS // The resource file for this implementationLIBRARY ECOM.lib // ECOM plug-in DLLs must link against ECOM.libLIBRARY ...// Other libraries as requiredThe plug-in is a polymorphic Symbian OS DLL and must define astandard DLL entry point as follows:TBool E32Dll(){return (ETrue);}Within a plug-in DLL, an ECOM interface collection may contain oneor more implementations of one or more ECOM interfaces and/or multipleimplementations of the same interface.
The sample code implements twosubclasses of CCryptoInterface.// implementation_uid = 0x10008EE5 (discussed later)class CSoftwareCrypto : public CCryptoInterface{IMPLEMENTING AN ECOM INTERFACE241public:static CSoftwareCrypto* NewL();∼CSoftwareCrypto();// Implementation using a software cryptography libraryvirtual void EncryptL(TDesC8& aPlaintext, TDesC8& aKey,TDes8& aCiphertext);virtual void DecryptL(TDesC8& aCiphertext, TDesC8& aKey,TDes8& aPlaintext);private:CSoftwareCrypto();void ConstructL();private:... // Omitted for clarity};// implementation_uid = 0x10008EE4 (discussed later)class CHardwareCrypto : public CCryptoInterface{public:static CHardwareCrypto* NewL();∼CHardwareCrypto();// Implementation using hardware & device driversvirtual void EncryptL(TDesC8& aPlaintext, TDesC8& aKey,TDes8& aCiphertext);virtual void DecryptL(TDesC8& aCiphertext, TDesC8& aKey,TDes8& aPlaintext);private:CHardwareCrypto();void ConstructL();private:...
// Omitted for clarity};Besides the interface functions, every implementation must have aninstantiation function which it ”registers” with ECOM. The classes aboveeach define a static NewL() factory function, which uses two-phaseconstruction as described in Chapter 4.ECOM calls the NewL() factory function of a class when a call toREComSession::CreateImplementationL() specifies that classdirectly or a given cue resolves to that implementation.A plug-in DLL ”registers” these instantiation functions with ECOMby exporting a standard function (ImplementationGroupProxy())which returns a pointer to an array of TImplementationProxy objects.This is the only function that a polymorphic ECOM plug-in DLL exports.Each TImplementationProxy object represents a single implementation class and contains the TUid which identifies the implementation(this should match the implementation_uid value for the class in itsregistration resource file) and a pointer to its instantiation method.#include <ImplementationProxy.h> // ECOM header file#include "CHardwareCrypto.h"// Class definition for CHardwareCrypto#include "CSoftwareCrypto.h"// Class definition for CSoftwareCrypto242ECOM// An array of TImplementationProxy objects which connect each// implementation with its instantiation functionconst TImplementationProxy ImplementationTable[] ={{{0x10008EE4}, CHardwareCrypto::NewL},{{0x10008EE5}, CSoftwareCrypto::NewL}};// Exported proxy function to resolve instantiation methods for an ECOM// plug-in DLLEXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt&aTableCount){aTableCount = sizeof(ImplementationTable) /sizeof(TImplementationProxy);return ImplementationTable;}Slightly confusingly, ECOM uses a number of different UIDs foridentification:14.5•interface_uid is used to identify a specific interface•implementation_uid is used to identify each concrete classthat implements an interface•an ECOM plug-in DLL, which can contain one or more ECOMinterface implementations, is identified using UID3 for the DLL(as described in Chapter 13).Resource FilesEarlier, I briefly mentioned that ECOM uses resource files to build upa ”registry” of all the ECOM plug-ins installed.
Let’s now examine thedetail. Each plug-in DLL must supply a compiled .rss resource, ofa particular format, in order to register with the ECOM framework.Both the plug-in DLL and the resource file should be built into the\system\libs\plugins\ directory.The resource file lists all the plug-in properties, including informationabout each concrete class implementing an ECOM interface. ECOMassociates the resource file with the plug-in DLL by name – it should benamed using the hexadecimal value of the third UID of the plug-in DLL(for the example below, this is 10008EE1.rss).RESOURCE FILES243// 10008EE1.RSS// Registry file for the CCryptoInterface Implementation Collection#include "RegistryInfo.rh" // Defines the resource structuresRESOURCE REGISTRY_INFO theInfo{// UID3 for the plug-in; must match the name of this filedll_uid = 0x10008EE1;interfaces = // interfaces info{INTERFACE_INFO{interface_uid = 0x10008EE0; // UID of CCryptoInterfaceimplementations ={IMPLEMENTATION_INFO // Info for CHardwareCrypto{// Identifies the specific implementationimplementation_uid = 0x10008EE4;version_no = 1;display_name = "Hardware Cryptography";// Used for cue lookup by the default ECOM resolverdefault_data = "HW";opaque_data = "";},IMPLEMENTATION_INFO // Info for CSoftwareCrypto{// Identifies the specific implementationimplementation_uid = 0x10008EE5;version_no = 1;display_name = "Software Cryptography";// Used for cue lookup by the default ECOM resolverdefault_data = "SW";opaque_data = "";}};}};}A single REGISTRY_INFO structure is used to declare all the implementations of ECOM interfaces (identified by interface_uid) availablein the plug-in DLL (identified by dll_uid).
The details of each implementation are declared inside separate IMPLEMENTATION_INFO structures.The default ECOM resolver uses the default_data attribute to resolvea cue passed to a factory instantiation function. In addition, it is possibleto customize the resolver to use the opaque_data attribute for lookup.Customized resolution can be useful to extend the selection criteriafrom those of the default ECOM resolver, for example by implementingcase-insensitive lookup.244ECOMA customized resolver is actually an implementation of an ECOM interface, CResolver, and it should thus be implemented in an ECOM plug-inDLL and registered with ECOM by supplying a resource file as describedabove.