70 likes | 148 Views
Purposes. Dynamically load libraries during program execution. Only the part that is necessary for current execution is loaded Each DLL module can be developed independently and seperately. Two kinds of DLL Static interface DLL Polymorphic interface DLL. Module Definition File.
E N D
Purposes • Dynamically load libraries during program execution. • Only the part that is necessary for current execution is loaded • Each DLL module can be developed independently and seperately. • Two kinds of DLL • Static interface DLL • Polymorphic interface DLL
Module Definition File • static interface DLLs use an import library (lib) to obtain relevant information about exported functions. • In conventional systems, DLLs may export by name or by ordinal. • Symbian OS only supports exporting by ordinal. • Exporting by ordinal reduces the time taken to find the item in the DLL export table and also reduces the size of the DLL as names need not be stored. • Ordinals are used for accessing the address of a function in the DLL export table. • It is only necessary to create def file for a polymorphic interface DLL, static interface DLLs use an import library to obtain relevant information about exported functions.
Module Definition File EXPORTS ??1CMyBase@@UAE@XZ @ 1 NONAME ; CMyBase::~CMyBase(void) ?NewL@CMyBase@@SAPAV1@PAVCConsoleBase@@ABVTDesC16@@@Z @ 2 NONAME ; class CMyBase * CMyBase::NewL(class CConsoleBase *, class TDesC16 const &) ?StartDoing@CMyBase@@QAEXXZ @ 3 NONAME ; void CMyBase::StartDoing(void) _E32Dll=__E32Dll ; Entry point for emulation
Polymorphic interface DLL • A polymorphic interface DLL is one which is written to implement a programming interface defined elsewhere; for example, a device driver, an application or an OPL extension. • The API is defined in terms of a single abstract class whose functions are declared as pure virtual. The DLL implements the API by defining and implementing a concrete class derived from that abstract class. • The DLL exports a single function whose sole purpose is to create an object of the derived class type; this is always the function at ordinal 1 within the DLL. • All other functions in the DLL are called through the virtual table mechanism (the pointer to the vtable is set up by the constructor in the normal C++ way). • The user of a dynamically loaded DLL uses an RLibrary type object to load the DLL. The RLibrary object encapsulates a handle to the DLL and must remain in existence while the DLL is in use; typically this is for the life of the object provided by the DLL.
Locating a DLL • A polymorphic DLL is loaded by calling one of the Load() member functions of an RLibrary object. • Load() has three overloaded variants but they all behave in a similar way. They are prototyped: • TInt Load(const TDesC& aFileName,const TDesC& aPath,const TUidType& aType); • TInt Load(const TDesC& aFileName,const TUidType& aType); • TInt Load(const TDesC& aFileName,const TDesC& aPath=KNullDesC); • Drives are searched in the order: C:(the device's main internal drive), then Y:, X:, W:, V:, U:, ..., D:, B:, A: and finally, drive Z: (the ROM).
How to define the interface to a polymorphic interface DLL • The interface is defined by an abstract API which can be implemented by a DLL. The following code fragment defines the API in terms of a pure virtual abstract C++ class; this is an example class called CMessenger. class CMessenger : public CBase {public: virtual void ConstructL(CConsoleBase* aConsole, const TDesC& aName)=0; virtual void ShowMessage()=0;private: CConsoleBase* iConsole; HBufC* iName; }; // The UID for Messenger DLLs.// The client imposes this on DLLs which satisfy the protocol.const TInt KMessengerUidValue=0x10004262;const TUid KMessengerUid={KMessengerUidValue};
How to use a polymorphic interface DLL • The following code can use any implementation of the interface defined by the example class, CMessenger, to issue a simple greeting. void UseDllL(const TFileName& aLibraryName,const TDesC& aName) { // Use RLibrary object to interface to the DLL RLibrary library; // Dynamically load the DLL TUidType uidType(KDynamicLibraryUid,KMessengerUid); User::LeaveIfError(library.Load(aLibraryName,uidType)); // Function at ordinal 1 creates new CMessenger TLibraryFunction entry=library.Lookup(1); // Call the function to create new CMessenger CMessenger* messenger=(CMessenger*) entry(); // Push pointer to CMessenger onto the cleanup stack CleanupStack::PushL(messenger); // Second-phase constructor for CMessenger messenger->ConstructL(console, aName); // Use Cmessenger object to issue greeting messenger->ShowMessage(); // Pop CMessenger object off cleanup stack and destroy CleanupStack::PopAndDestroy(); // Finished with the DLL library.Close(); }