Compartir a través de


Ejemplo para resolver conflictos de nombre de función

Tenga en cuenta lo siguiente.

  • IADs0 no admite Func0.
  • IADs1 admite Func1 y Func0.
  • IADs2 admite Func2 y Func0.

Las tres interfaces son interfaces duales.

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

Tenga en cuenta que aunque IADs1 no admita Func2, un cliente ADSI reconoce un IDispatch que admite todas las interfaces duales y de envío en el modelo. Por lo tanto, el cliente ADSI puede llamar directamente a Func2 mediante myInf1.Func2 sin resolver qué interfaz admite Func2.

myInf1.Func2

Ambos IADs1 e IADs2 tienen una función denominada Func0, pero IADs1::Func0 se invoca directamente mediante el acceso de vtable, ya que ambos de los siguientes se aplican al cliente:

  • El cliente tiene un puntero al objeto IADs1 de interfaz dual, que tiene una función denominada Func0.
  • Visual Basic admite el acceso directo a la tabla virtual, suponiendo que el tipo de datos está disponible a través de la biblioteca de tipos.

En el ejemplo de código siguiente, el cliente tiene un puntero de interfaz dual a IADs2 en lugar de IADs1. Por lo tanto, se invoca IADs2::Func0 mediante el acceso directo a vtable.

Dim myInf2 as IADs2
Set myInf2 = myInf1 ' Query for pointer to IADs2 
myInf2.Func0

De nuevo, en el siguiente ejemplo de código, los IADs1 e IADs2 tienen una función denominada Func0, pero, aquí, el cliente tiene un puntero a una interfaz dual, IADs0, que no tiene una función denominada Func0. Por lo tanto, no se puede realizar ningún acceso directo a la tabla virtual. En su lugar, se llama a IDispatch::GetIDsOfNames e Invoke para invocar Func0.

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

Tenga en cuenta estos dos casos:

  • LOS IAD1 e IAD2 se implementan mediante dos componentes COM, Ext1 y Ext2, respectivamente. Si Ext1 viene antes de Ext2 en el registro, se invoca IADs1::Func0. Sin embargo, si Ext2 viene primero en el registro, se invoca IADs2::Func0.
  • Si iaDs1 y ADs2 se implementan mediante el mismo objeto de extensión, func0 siempre se invoca mediante los métodos IADsExtension::P rivateGetIDsOfNames y PrivateInvoke de la extensión.

El desarrollador de extensiones debe determinar cómo resolver conflictos de funciones, o propiedades, de interfaces IDispatch duales diferentes que tengan el mismo nombre en una extensión. La implementación de los métodos IADsExtension::P rivateGetIDsOfNames y PrivateInvoke deben resolver este conflicto. Por ejemplo, si usa IMyInterface1::Func1 e IMyInterface2::Func1, donde IMyInterface1 e IMyInterface2 son interfaces IDispatch duales compatibles con el mismo objeto de extensión. Los métodos PrivateGetIDsOfNames y PrivateInvoke deben determinar a qué func1 se debe llamar siempre.

Lo mismo se aplica a los DISPID en conflicto en diferentes interfaces duales o IDispatch .

Por ejemplo, el DISPID de IMyInterface1::Y es 2 en el archivo imyinterface1.odl, o imyinterface1.idl. El DISPID de IMyInterface2::X también es 2 en iMyInterface2.odl. IADsExtension::P rivateGetIDsOfNames debe devolver un DISPID único, dentro de la propia extensión, para cada uno, en lugar de devolver el mismo DISPID para ambos.

ADSI resuelve el primer problema al no admitir varias interfaces con nombres de función o propiedad en conflicto. Resuelve el segundo problema agregando un único, que se encuentra dentro del mismo objeto de extensión, número de interfaz a los bits no usados del DISPID.