Platform SDK: Active Directory, ADSI, and Directory Services |
Consider the following assumptions:
All three interfaces are dual interfaces.
IADs0 : IDispatch { OtherFunc(); } |
IADs1 : IDispatch { Func0() Func1(); } |
IADs2 : IDispatch { Func0() Func2(); } |
Dim myInf1 as IADs1 myInf1.Func1 ' IADs1::Func1 is invoked using direct vtable access myInf1.Func2 ' IADs2::Func2 is invoked using GetIDsOfNames/Invoke
Note that even though IADs1 does not support Func2, an ADSI client sees one IDispatch which supports all the dual and dispatch interfaces in our model. Thus, the ADSI client can directly call Func2 using myInf1.Func2 without figuring out which interface supports Func2.
myInf1.Func2
Note that both IADs1 and IADs2 have a function called Func0, but IADs1::Func0 is invoked directly using vtable access, because the following apply to the client:
In the next example, the client has a dual interface pointer to IADs2 instead of IADs1. Therefore, IADs2::Func0 is invoked using direct vtable access.
Dim myInf2 as IADs2 Set myInf2 = myInf1 ' Querying for pointer to IADs2 myInf2.Func0
Again, in the next example, both IADs1 and IADs2 have a function called Func0, but this time the client has a pointer to a dual interface, IADs0, which does not have a function called Func0. Therefore, no direct vtable access can be performed. Instead, IDispatch::GetIDsOfNames/Invoke are called to invoke Func0.
Dim myInfNone as IADs0 Set myInfNone = myInf1 ' The aggregated object which ' supports both IADs1 & IADs2. myInfNone.Func0
Consider these two cases:
It's completely up to the extension developer to determine how to resolve conflicts of functions (or properties) of different dual IDispatch interfaces that have the same name in an extension. The implementation of IADsExtension::PrivateGetIDsOfNames and PrivateInvoke methods should resolve this conflict. For example, if you use IFoo::Func1 and IMoreFoo::Func1, where IFoo and IMoreFoo are dual IDispatch interfaces supported by the same extension object. The PrivateGetIDsOfNames and PrivateInvoke methods must determine which Func1 should always be called.
The same applies to conflicting DISPIDs in different dual or IDispatch interfaces.
For example, the DISPID of IFoo::Y is 2 in the file ifoo.odl (or ifoo.idl). The DISPID of IMoreFoo::X is also 2 in imorefoo.odl. IADsExtension::PrivateGetIDsOfNames must return a unique DISPID (within the extension itself) for each, instead of returning the same DISPID for both.
ADSI resolves the first problem by not supporting multiple interfaces with conflicting function or property names. It resolves the latter problem by adding a unique (within the same extension object) interface number to the unused bits of the DISPID.