|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-301193C2-666C-5A57-B898-A04EBB63E533" xml:lang="en"><title>How to |
|
13 use a polymorphic interface DLL</title><shortdesc>The example issues a greeting to the person whose name is passed |
|
14 in the descriptor <codeph>aName</codeph>.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
15 <p>The following code can use any implementation of the interface defined |
|
16 by the example class, <codeph>CMessenger</codeph>, to issue a simple greeting.</p> |
|
17 <p> The name of the DLL, which contains the implementation to be used, is |
|
18 passed in the descriptor <codeph>aLibraryName</codeph>.</p> |
|
19 <codeblock id="GUID-3BBCFE9F-7D77-563A-AE87-4BBE2B7F195E" xml:space="preserve">void UseDllL(const TFileName& aLibraryName,const TDesC& aName) |
|
20 { |
|
21 // Use RLibrary object to interface to the DLL |
|
22 RLibrary library; |
|
23 // Dynamically load the DLL |
|
24 TUidType uidType(KDynamicLibraryUid,KMessengerUid); |
|
25 User::LeaveIfError(library.Load(aLibraryName,uidType)); |
|
26 // Function at ordinal 1 creates new CMessenger |
|
27 TLibraryFunction entry=library.Lookup(1); |
|
28 // Call the function to create new CMessenger |
|
29 CMessenger* messenger=(CMessenger*) entry(); |
|
30 // Push pointer to CMessenger onto the cleanup stack |
|
31 CleanupStack::PushL(messenger); |
|
32 // Second-phase constructor for CMessenger |
|
33 messenger->ConstructL(console, aName); |
|
34 // Use Cmessenger object to issue greeting |
|
35 messenger->ShowMessage(); |
|
36 // Pop CMessenger object off cleanup stack and destroy |
|
37 CleanupStack::PopAndDestroy(); |
|
38 // Finished with the DLL |
|
39 library.Close(); |
|
40 }</codeblock> |
|
41 <section id="GUID-738C30CA-1A75-4038-8BB4-68682D3C539C"><title>Notes:</title> <ul> |
|
42 <li id="GUID-01B13D4C-7028-5987-B993-213E6FE9E571"><p>the <codeph>RLibrary</codeph> class |
|
43 is the interface to dynamically loaded DLLs. It encapsulates a handle to the |
|
44 DLL.</p> </li> |
|
45 <li id="GUID-726B2AA5-7674-5DA1-B6FA-EB10F85D7D1F"><p>The DLL has a <codeph>TUidType</codeph> which |
|
46 is assigned when the DLL is built. This is ensures that the DLL that is loaded |
|
47 complies with the <codeph>CMessenger</codeph> protocol.</p> </li> |
|
48 <li id="GUID-F5F2DAE3-62B2-5690-92FF-85AF3F8C987F"><p>If a specific implementation |
|
49 of the DLL is to be used, then specify a third UID when declaring the TUidType. |
|
50 Each specific implementation of the DLL is uniquely identified by the third |
|
51 UID.</p> </li> |
|
52 <li id="GUID-C24783C0-CCFA-5AF1-9941-7FB5D0504756"><p>A pointer to the ordinal |
|
53 1 function in the DLL is fetched by calling the <codeph>Lookup()</codeph> member |
|
54 function of <codeph>RLibrary</codeph> and passing it a parameter value of |
|
55 1. The returned function has type <codeph>TLibraryFunction</codeph>; such |
|
56 a function takes no parameters and returns a <codeph>TAny*</codeph> type.</p> </li> |
|
57 <li id="GUID-C1FB1A45-A02A-5B10-B1EA-AE84982DB6BC"><p>The function pointer |
|
58 is assigned to the variable called <codeph>entry</codeph> and the function |
|
59 itself is called to construct a <codeph>CMessenger</codeph> object and return |
|
60 a pointer to that object. The implementation uses the <codeph>new (ELeave)</codeph> operator |
|
61 to allocate the new <codeph>CMessenger</codeph> object and invoke the C++ |
|
62 default constructor.</p> </li> |
|
63 <li id="GUID-1A7CBF75-9059-5AED-ABA9-DF649D613988"><p>As no arguments are |
|
64 passed to the function, a second-phase constructor, <codeph>ContructL()</codeph>, |
|
65 is called to finish off construction.</p> </li> |
|
66 <li id="GUID-B58DFA44-368F-578B-B35D-7DBF1C67A83A"><p>The <codeph>CMessenger</codeph> object |
|
67 can then be used like any other C++ object. In this example, the <codeph>ShowMessage()</codeph> function |
|
68 is used to emit a greeting in whatever way the implementation chooses. In |
|
69 more complex cases, the object could have a long lifetime, and create many |
|
70 dependent objects.</p> </li> |
|
71 <li id="GUID-67D8B0AA-8425-52C1-851A-D022B7847448"><p>When the <codeph>CMessenger</codeph> object |
|
72 is no longer needed, the DLL is unloaded using <codeph>RLibrary::Close()</codeph>. |
|
73 Do not call any code in the DLL after the library has been closed. It is important |
|
74 to note, therefore, that the library must not be closed until the object constructed |
|
75 by the DLL, <i>and all its dependent objects</i>, have been destroyed.</p> </li> |
|
76 </ul> </section> |
|
77 </conbody></concept> |