Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Symbian OS Explained - Effective C++ Programming For Smartphones (2005) [eng].pdf
Скачиваний:
60
Добавлен:
16.08.2013
Размер:
2.62 Mб
Скачать

242

ECOM

// An array of TImplementationProxy objects which connect each

//implementation with its instantiation function const TImplementationProxy ImplementationTable[] =

{

{{0x10008EE4}, CHardwareCrypto::NewL}, {{0x10008EE5}, CSoftwareCrypto::NewL} };

//Exported proxy function to resolve instantiation methods for an ECOM

//plug-in DLL

EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)

{

aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);

return ImplementationTable;

}

Slightly confusingly, ECOM uses a number of different UIDs for identification:

interface_uid is used to identify a specific interface

implementation_uid is used to identify each concrete class that implements an interface

an ECOM plug-in DLL, which can contain one or more ECOM interface implementations, is identified using UID3 for the DLL (as described in Chapter 13).

14.5Resource Files

Earlier, I briefly mentioned that ECOM uses resource files to build up a ”registry” of all the ECOM plug-ins installed. Let’s now examine the detail. Each plug-in DLL must supply a compiled .rss resource, of a 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 information about each concrete class implementing an ECOM interface. ECOM associates the resource file with the plug-in DLL by name – it should be named using the hexadecimal value of the third UID of the plug-in DLL (for the example below, this is 10008EE1.rss).

RESOURCE FILES

243

//10008EE1.RSS

//Registry file for the CCryptoInterface Implementation Collection

#include "RegistryInfo.rh" // Defines the resource structures

RESOURCE REGISTRY_INFO theInfo

{

// UID3 for the plug-in; must match the name of this file dll_uid = 0x10008EE1;

interfaces = // interfaces info

{

INTERFACE_INFO

{

interface_uid = 0x10008EE0; // UID of CCryptoInterface

implementations =

{

IMPLEMENTATION_INFO // Info for CHardwareCrypto

{

//Identifies the specific implementation implementation_uid = 0x10008EE4; version_no = 1;

display_name = "Hardware Cryptography";

//Used for cue lookup by the default ECOM resolver default_data = "HW";

opaque_data = ""; },

IMPLEMENTATION_INFO // Info for CSoftwareCrypto

{

//Identifies the specific implementation implementation_uid = 0x10008EE5; version_no = 1;

display_name = "Software Cryptography";

//Used for cue lookup by the default ECOM resolver default_data = "SW";

opaque_data = "";

}

};

}

};

}

A single REGISTRY_INFO structure is used to declare all the implementations of ECOM interfaces (identified by interface_uid) available in 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 resolve a cue passed to a factory instantiation function. In addition, it is possible to customize the resolver to use the opaque_data attribute for lookup. Customized resolution can be useful to extend the selection criteria from those of the default ECOM resolver, for example by implementing case-insensitive lookup.

244

ECOM

A customized resolver is actually an implementation of an ECOM interface, CResolver, and it should thus be implemented in an ECOM plug-in DLL and registered with ECOM by supplying a resource file as described above. The interface_uid for CResolver is 0x10009D0 – you should always use this value in the resource file created for your custom resolver.

Such a resolver must implement the pure virtual functions

IdentifyImplementationL() and ListAllL() declared in

CResolver. It should also specify a factory creation function which takes an MPublicRegistry reference parameter; this object gives the resolver access to a list of implementations of a specified interface.

IdentifyImplementationL() should be implemented to identify the most appropriate implementation of a specified interface, according to a cue. It will use the MPublicRegistry object to obtain information about each implementation. ListAllL() must return a list of all implementations which match the cue.

class CCryptoResolver : public CResolver

{

public:

// Factory function

static CCryptoResolver* NewL(MPublicRegistry& aRegistry);

CCryptoResolver();

public: // From CResolver (see resolver.h)

/** Request that the resolver identify the most appropriate interface implementation, returning the UID or KNullUid if no match is found */

TUid IdentifyImplementationL(TUid aInterfaceUid,

const TEComResolverParams& aAdditionalParameters) const;

/** Return a pointer to an array of all the implementations which satisfy the specified interface */

RImplInfoArray* ListAllL(TUid aInterfaceUid,

const TEComResolverParams& aAdditionalParameters) const;

... // Omitted };

The custom resolver may be used by the interface instantiation functions; for example, the CCryptoInterface::NewL() factory method may be extended to use a custom resolver as follows:

CCryptoInterface* CCryptoInterface::NewL()

{// The implementation instantiated is the first found by resolver

_LIT8(KAny,"*");

TEComResolverParams resolverParams;

resolverParams.SetDataType(KAny());

resolverParams.SetWildcardMatch(ETrue);

EXAMPLE CLIENT CODE

245

// UID of the crypto resolver

const TUid KCustomResolverUid = {0x10008EE6};

TAny* cryptoInterface = REComSession::CreateImplementationL(KCCryptoInterfaceUid, _FOFF(CCryptoInterface,iDtor_ID_Key), NULL, resolverParams, KCustomResolverUid));

return (reinterpret_cast<CCryptoInterface*>(cryptoInterface));

}

The third UID of an ECOM plug-in DLL is used to name its associated compiled resource, which contains its ECOM ”registration” information.

14.6 Example Client Code

So how does a client use an ECOM plug-in? As I have already described, the caller doesn’t need to be aware of the details and simply uses the factory function supplied by the interface, supplying a cue if it is required. ECOM takes care of the details of locating and instantiating the appropriate implementation. An interface client must simply include the header files which define the interface, link against ECOM.lib and use the factory instantiation functions as appropriate:

#include "CryptoInterface.h"

void GetDefaultCryptoL()

{// Get the default implementation of CCryptoInterface CCryptoInterface* crypto = CCryptoInterface::NewL(); CleanupStack::PushL(crypto);

...

CleanupStack::PopAndDestroy(crypto);

}

void GetSpecifiedCryptoL()

{// Use a cue - gets CCryptoInterface implementation which uses // hardware support

_LIT8(KHardware,"HW");

CCryptoInterface* crypto = CCryptoInterface::NewL(KHardware);

CleanupStack::PushL(crypto);

...

CleanupStack::PopAndDestroy(crypto);

}

void GetAllCryptoL()

{

//Get all implementations using CCryptoInterface::ListImplementationsL() RImplInfoPtrArray infoArray;