|
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 task |
|
11 PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd"> |
|
12 <task id="GUID-50E6EEB5-45D2-5B95-BDEA-5615F586DA9C" xml:lang="en"><title>Using |
|
13 Extended Interfaces</title><shortdesc>Framework developers define and publish extension interfaces to |
|
14 the existing interfaces used in the framework. Once an interface extension |
|
15 is published by the framework developer, plug-in developers implement the |
|
16 extension if required. </shortdesc><prolog><metadata><keywords/></metadata></prolog><taskbody> |
|
17 <steps id="GUID-D3DD03B6-79C0-5C7A-B263-A4AC2E50266E"> |
|
18 <step id="GUID-BA6F73F2-BA5C-5A2B-A405-D2FD99C06954"><cmd/> |
|
19 <info>Identify the published instantiation and extended interface UIDs and |
|
20 header files of the framework. </info> |
|
21 </step> |
|
22 <step id="GUID-27966E9C-33EF-5BC3-9E5E-FA3C68A60AFD"><cmd/> |
|
23 <info>Create a <xref href="GUID-641A276D-F618-50CE-BA5A-658DCC26BAB5.dita">new |
|
24 project file</xref> (<filepath>.mmp</filepath>) with <codeph>targettype</codeph> variable |
|
25 set as PLUGIN3. Allocate UIDs for the the plug-in implementations and plug-in |
|
26 DLL (UID3) as shown in the code snippet below. </info> |
|
27 <stepxmp><codeblock id="GUID-080E8FC5-5114-5CBE-BF83-C7E4164CC0CC" xml:space="preserve">TARGET cimplementationclass.dll |
|
28 TARGETTYPE PLUGIN3 |
|
29 CAPABILITY All -TCB |
|
30 |
|
31 // PLUGIN3 recognition UID followed by the UID for this dll |
|
32 UID 0x10009D93 0x10009E37 |
|
33 VENDORID 0x70000001 |
|
34 |
|
35 SOURCEPATH ../src |
|
36 SOURCE cimplementationclass.cpp |
|
37 |
|
38 USERINCLUDE ../src |
|
39 SYSTEMINCLUDE /epoc32/include |
|
40 |
|
41 START RESOURCE cimplementationclass.rss |
|
42 TARGET cimplementationclass.rsc |
|
43 END |
|
44 |
|
45 LIBRARY euser.lib |
|
46 LIBRARY ecom.lib |
|
47 </codeblock> </stepxmp> |
|
48 </step> |
|
49 <step id="GUID-E9B72208-C9EB-50C3-A5FE-849D34371314"><cmd/> |
|
50 <info>Create a new resource file (<filepath>.rss</filepath>) of <xref href="GUID-9A9103E4-27B0-5CF3-855A-DCD44795A5C0.dita">format |
|
51 version 3</xref>. </info> |
|
52 <stepxmp><codeblock id="GUID-33EB82EB-1CD7-5213-9B74-3F760290795E" xml:space="preserve">CImplementationClass.rss |
|
53 #include <ecom/registryinfov3.rh> |
|
54 |
|
55 RESOURCE REGISTRY_INFO theInfo |
|
56 { |
|
57 resource_format_version = RESOURCE_FORMAT_VERSION_3; |
|
58 dll_uid = 0x10009E37; |
|
59 interfaces = |
|
60 { |
|
61 INTERFACE_INFO |
|
62 { |
|
63 instantiation_interface_uid = 0x10009DBB; |
|
64 implementations = |
|
65 { |
|
66 IMPLEMENTATION_INFO |
|
67 { |
|
68 info_format = IMPLEMENTATION_INFO_RECORD_TYPE1; |
|
69 implementation_uid = 0x10009E38; |
|
70 version_no = 1; |
|
71 display_name = "Extended Interface Example"; |
|
72 default_data = {"Extended Interface Example||up to 255 chars", "Max. two strings allowed"}; |
|
73 opaque_data = {"up to 255 chars", “max. 2 strings allowed”}; |
|
74 extended_interfaces = {0x10009E44, 0x10009E45}; |
|
75 flags = FLAG_ROM_ONLY; |
|
76 } |
|
77 }; |
|
78 } |
|
79 }; |
|
80 } |
|
81 </codeblock> </stepxmp> |
|
82 </step> |
|
83 <step id="GUID-5D92F8AC-6440-5426-A79A-8D5CBE6D2E60"><cmd/> |
|
84 <info>Implement the interfaces in the plug-in implementation source files. </info> |
|
85 <info>Implementing an interface extension in a plug-in implementation can |
|
86 be done in either of the two ways: </info> |
|
87 <substeps id="GUID-3FCA938B-5515-5707-B583-08A398B138C3"> |
|
88 <substep id="GUID-34A3E29D-0195-5B41-AAA9-F8A9EDF6BCA0"><cmd/> |
|
89 <info> Inheritance: The instantiation interface object is also of the type |
|
90 of the extended interface object. When a user wants to instantiate the extended |
|
91 interface object, the implementation simply returns a re-cast of the instantiation |
|
92 interface object. </info> |
|
93 <info>The example below shows implementing an interface extension using inheritance. </info> |
|
94 <stepxmp><codeblock id="GUID-CE4895D9-14DB-55A5-8D61-36C4613DF453" xml:space="preserve">//Implementing an interface extension using multiple inheritance |
|
95 class CImplementationClass : public CExampleInterface, public MExampleInterfaceExtended |
|
96 { |
|
97 |
|
98 public: |
|
99 static CImplementationClass* NewL(); |
|
100 static TAny* GetExtendedInterfaceL(TAny* aInstantiationInterface,const TUid& aExtendedInterfaceUid,TUint32& aBitFlags,TAny*& aReleaseObject); |
|
101 static void ReleaseExtendedInterface(TAny* aExtendedInterface, const TUid& aExtendedInterfaceUid); |
|
102 |
|
103 ~ CImplementationClass() {} |
|
104 virtual void DoMethodL(); // from original interface |
|
105 virtual void DoMethodExtended(); //from MExampleInterfaceExtended |
|
106 private: |
|
107 CImplementationClass() {} |
|
108 }; |
|
109 |
|
110 </codeblock> </stepxmp> |
|
111 </substep> |
|
112 <substep id="GUID-C9A0347A-1EC9-5D30-A6DF-57E0C121387E"><cmd/> |
|
113 <info> Realizing the extended interface as separate class and objects. When |
|
114 users fetch the extended interface object, the implementation allocates a |
|
115 new object. </info> |
|
116 <info>The example below shows implementing an interface extension using realisation. </info> |
|
117 <stepxmp><codeblock id="GUID-99C45102-442C-56F5-8054-3C88C64FE1DE" xml:space="preserve">// Implementing an interface extension using realization |
|
118 |
|
119 class CImplementationClassExtended : public CBase, public MExampleInterfaceExtended2 |
|
120 { |
|
121 public: |
|
122 static CImplementationClassExtended* NewL(); |
|
123 ~ CImplementationClassExtended() {} |
|
124 virtual void DoMethodExtended2(); //from MExampleInterfaceExtended2 |
|
125 private: |
|
126 CImplementationClassExtended() {} |
|
127 }; |
|
128 </codeblock> </stepxmp> |
|
129 </substep> |
|
130 </substeps> |
|
131 </step> |
|
132 <step id="GUID-2E92FD5E-03E0-5587-B6D1-0CA7EEDBFA44"><cmd/> |
|
133 <info>Implement <xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-C7F147AC-6D77-3169-AAB4-B27262B4333B"><apiname>REComSession::CreateImplementationL()</apiname></xref>,<xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-760E4CCE-8E33-3B72-B143-380503F6ACC5"><apiname>REComSession::GetExtendedInterfaceL()</apiname></xref>,<xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-8F83D14E-F340-32B4-969C-5DC9E6EA1DB0"><apiname>REComSession::ManuallyReleaseExtendedInterfaceL()</apiname></xref> functions of the instantiation interface. </info> |
|
134 <stepxmp><codeblock id="GUID-FC783C9A-1990-5DDB-9266-6469B9558EE0" xml:space="preserve">TAny* CImplementationClass::GetExtendedInterfaceL(TAny* aInstantiationInterface, |
|
135 const TUid& aExtendedInterfaceUid, |
|
136 TUint32& aBitFlags, |
|
137 TAny*& aReleaseObject) |
|
138 { |
|
139 TAny* ret = NULL; |
|
140 aBitFlags &= ~KReleaseRequiredMask; // clear release flag |
|
141 switch (aExtendedInterfaceUid.iUid) |
|
142 { |
|
143 case 0x10009E44: |
|
144 { |
|
145 // release not required, so do not modify aBitFlags. |
|
146 // re-cast Instantiation object as Extended Interface object |
|
147 ret = static_cast<MExampleInterfaceExtended *> (static_cast<CImplementationClass *>(aObject)); |
|
148 break; |
|
149 } |
|
150 case 0x10009E45: |
|
151 { |
|
152 CImplementationClassExtended *classExt = CImplementationClassExtended::NewL(); |
|
153 aReleaseObject = classExt; |
|
154 aBitFlags |= KReleaseRequiredMask; // Indicate release is required |
|
155 // Multiple inheritance involved – Cbase and the M class. Must use |
|
156 // either dynamic_cast or static_cast to add offset to the base pointer |
|
157 ret = static_cast<MExampleInterfaceExtended2*>(classExt); |
|
158 break; |
|
159 } |
|
160 } |
|
161 return ret; |
|
162 } |
|
163 </codeblock> </stepxmp> |
|
164 <info>The plug-in framework releases the extended interface object when the |
|
165 user destroys the instantiation interface object. Alternatively, if the framework |
|
166 wants to release the extended interface earlier, they can call the <xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-8F83D14E-F340-32B4-969C-5DC9E6EA1DB0"><apiname>REComSession::ManuallyReleaseExtendedInterfaceL()</apiname></xref> </info> |
|
167 <stepxmp><codeblock id="GUID-A058A010-9875-52F6-ABF2-8B329F50B750" xml:space="preserve">void CImplementationClass::ReleaseExtendedInterface(TAny* aExtendedInterface, const TUid& aExtendedInterfaceUid) |
|
168 { |
|
169 switch (aExtendedInterfaceUid.iUid) |
|
170 { |
|
171 case 0x10009E45: |
|
172 { |
|
173 // this Extended Interface object require release. |
|
174 CImplementationClassExtended* classExt = static_cast<CImplementationClassExtended*>(aReleaseObject); |
|
175 delete classExt; |
|
176 break; |
|
177 } |
|
178 } |
|
179 } |
|
180 </codeblock> </stepxmp> |
|
181 <info>The aInstanceKey parameter is returned by <xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-C7F147AC-6D77-3169-AAB4-B27262B4333B"><apiname>REComSession::CreateImplementationL()</apiname></xref>. |
|
182 It identifies the instantiation interface object instance. The aExtendedInterfaceUid |
|
183 parameter identifies the extended interface required. </info> |
|
184 </step> |
|
185 <step id="GUID-6E73075E-E907-5984-9571-D7A77FC2D05A"><cmd/> |
|
186 <info>Export the instantiation functions into a TImplementationProxy3 table. </info> |
|
187 <stepxmp><codeblock id="GUID-7CFF8E49-3B6F-5DAB-883F-1347B907F77E" xml:space="preserve">const TImplementationProxy3 KImplementationTable[] = |
|
188 { |
|
189 IMPLEMENTATION_PROXY_ENTRY3(0x10009E38, CImplementationClass::NewL, CImplementationClass::GetExtendedInterfaceL,CImplementationClass::ReleaseExtenedInterface) |
|
190 }; |
|
191 |
|
192 EXPORT_C const TImplementationProxy3* ImplementationGroupProxy(TInt& aTableCount) |
|
193 { |
|
194 aTableCount = sizeof(KImplementationTable) / sizeof(TImplementationProxy3); |
|
195 return KImplementationTable; |
|
196 } |
|
197 |
|
198 </codeblock> </stepxmp> |
|
199 </step> |
|
200 <step id="GUID-5790D794-A201-5E9F-AE2E-DC698878CCF5"><cmd/> |
|
201 <info>Export the release functions into a TImplementationProxy3 table. </info> |
|
202 <stepxmp><codeblock id="GUID-22DB44AF-EDE6-52C0-ADBE-216F95E3FB5C" xml:space="preserve">void CImplementationClass::ReleaseExtendedInterface(TAny* aExtendedInterface, const TUid& aExtendedInterfaceUid) |
|
203 { |
|
204 switch (aExtendedInterfaceUid.iUid) |
|
205 { |
|
206 case 0x10009E45: |
|
207 { |
|
208 // this Extended Interface object require release. |
|
209 CImplementationClassExtended* classExt = static_cast<CImplementationClassExtended*>(aReleaseObject); |
|
210 delete classExt; |
|
211 break; |
|
212 } |
|
213 } |
|
214 } |
|
215 |
|
216 </codeblock> </stepxmp> |
|
217 </step> |
|
218 </steps> |
|
219 <postreq><p>To instantiate and use an extended interface, the plug-in user |
|
220 must: </p> <ul> |
|
221 <li id="GUID-A8A28B3D-D94E-5AC9-8C3F-275A4C8F89DE"><p>Identify plug-ins that |
|
222 support the desired interface extensions using <xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-AE9D4F24-8554-3151-AAF3-D63F400821C4"><apiname>REComSession::ListImplementationsL()</apiname></xref>. </p> <codeblock id="GUID-987C54C2-F1AF-57C6-95DA-37F1572AD1B4" xml:space="preserve">IMPORT_C static void ListImplementationsL(TUid aInterfaceUid, |
|
223 RExtendedInterfacesArray& aExtendedInterfaces, |
|
224 const TEComResolverParams& aResolutionParameters, |
|
225 RImplInfoPtrArray& aImplInfoArray); |
|
226 </codeblock> <p>The “aInterfaceUid” parameter specifies the instantiation |
|
227 interface. All of the implementations returned in “aImplInfoArray” support |
|
228 all the extensions listed in the “aExtendedInterfaces” parameter. </p> </li> |
|
229 <li id="GUID-ED513B5A-9F51-5B5C-AB58-E961CAFEFD92"><p>Select one from the |
|
230 array and create an instantiation interface object. </p> </li> |
|
231 <li id="GUID-C4A2263B-08D1-5D44-99B2-840EE4849B35"><p>Call <xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-760E4CCE-8E33-3B72-B143-380503F6ACC5"><apiname>REComSession::GetExtendedInterfaceL()</apiname></xref> API |
|
232 to get an extended interface object. </p> <codeblock id="GUID-B9EE4751-EA4B-5BB6-A6DA-3083FE0CCE36" xml:space="preserve">IMPORT_C static TAny* GetExtenedInterfaceL(const TUid& aInstanceKey, |
|
233 const TUid& aExtendedInterfaceUid); |
|
234 </codeblock> <p>The aInstanceKey parameter identifies the instantiation interface |
|
235 object returned by <xref href="GUID-1344F049-81C4-3D17-AF46-8B5584680ADB.dita#GUID-1344F049-81C4-3D17-AF46-8B5584680ADB/GUID-C7F147AC-6D77-3169-AAB4-B27262B4333B"><apiname>REComSession::CreateImplementationL()</apiname></xref>. </p> </li> |
|
236 </ul> <p>The example code depicts the above steps: </p> <codeblock id="GUID-5D0D622D-3CA6-5CDB-B035-F68A580949AA" xml:space="preserve"> |
|
237 const TUid KExampleInterfaceUid = {0x10009DBB}; // the Instantiation Interface |
|
238 const TUid KExtendedInterfaceUid1 = {0x10009E44}; |
|
239 const TUid KExtendedInterfaceUid2 = {0x10009E45}; |
|
240 |
|
241 // Set up extended interfaces UID list which form part of the resolution criteria. |
|
242 RArray<TUid> extendedInterfaces; |
|
243 CleanupClosePushL(extendedInterfaces); |
|
244 extendedInterfaces.AppendL(KExtendedInterfaceUid1); |
|
245 extendedInterfaces.AppendL(KExtendedInterfaceUid2); |
|
246 |
|
247 // set up resolve parameter |
|
248 _LIT8(KExampleImplementationData,"Extended Interface Example"); |
|
249 TEComResolverParams ResolverParams; |
|
250 ResolverParams.SetDataType(KExampleImplementationData()); |
|
251 ResolverParams.SetGenericMatch(ETrue); |
|
252 |
|
253 TUid instanceKey; |
|
254 CExampleInterface* instantiateIf = static_cast<CExampleInterface*>( |
|
255 REComSession::CreateImplementationL(KExampleInterfaceUid, |
|
256 extendedInterfaces, |
|
257 instanceKey, |
|
258 ResolverParams) ); |
|
259 CleanupStack::PopAndDestroy(&extendedInterfaces); |
|
260 |
|
261 CleanupStack::PushL(instantiateIf); |
|
262 // May want to TRAP here if KErrNotSupported is handled, i.e. extension optional |
|
263 MExampleInterfaceExtended2* ext2 = static_cast<MExampleInterfaceExtended2*>( |
|
264 REComSession::GetExtendedInterfaceL(instanceKey, KExtendedInterfaceUid2)); |
|
265 |
|
266 instantiateIf->DoMethodL(); // access old interface function |
|
267 ext2->DoMethodExtended2(); // access extension function |
|
268 |
|
269 // Calling ManuallyReleaseExtendedInterface is optional. Do this |
|
270 // if want to release extended object early. |
|
271 REComSession::ManuallyReleaseExtendedInterface(instanceKey,KExtendedInterfaceUid2); |
|
272 |
|
273 REComSession::DestroyedImplementation(instanceKey); |
|
274 CleanupStack::PopAndDestroy(instantiateIf); |
|
275 </codeblock> </postreq> |
|
276 </taskbody></task> |