Directory Services

Example Code for Resolving Function Name Conflicts

Consider the following:

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

Be aware that even though IADs1 does not support Func2, an ADSI client recognizes one IDispatch that supports all the dual and dispatch interfaces in the model. Thus, the ADSI client can directly call Func2 using myInf1.Func2 without resolving which interface supports Func2.

myInf1.Func2

Both IADs1 and IADs2 have a function called Func0, but IADs1::Func0 is invoked directly using vtable access, because both of following apply to the client:

In the next code 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 ' Query for pointer to IADs2 
myInf2.Func0

Again, in the next code example, both IADs1 and IADs2 have a function called Func0, but, here, 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 and Invoke are called to invoke Func0.

Dim myInfNone as IADs0
Set myInfNone = myInf1	' The aggregated object that 
						' supports IADs1 and IADs2.
myInfNone.Func0

Consider these two cases:

The extension developer must 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 IMyInterface1::Func1 and IMyInterface2::Func1, where IMyInterface1 and IMyInterface2 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 IMyInterface1::Y is 2 in the file imyinterface1.odl, or imyinterface1.idl. The DISPID of IMyInterface2::X is also 2 in iMyInterface2.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 second problem by adding a unique, that is within the same extension object, interface number to the unused bits of the DISPID.