Condividi tramite


Esempio per la risoluzione dei conflitti di nomi di funzione

Tenere presente quanto segue:

  • IADs0 non supporta Func0.
  • IADs1 supporta Func1 e Func0.
  • IADs2 supporta Func2 e Func0.

Tutte e tre le interfacce sono interfacce doppie.

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

Tenere presente che, anche se IADs1 non supporta Func2, un client ADSI riconosce un IDispatch che supporta tutte le interfacce dual e dispatch nel modello. Di conseguenza, il client ADSI può chiamare direttamente Func2 usando myInf1.Func2 senza risolvere quale interfaccia supporta Func2.

myInf1.Func2

Sia IADs1 che IADs2 hanno una funzione denominata Func0, ma IADs1::Func0 viene richiamata direttamente usando l'accesso alla tabella virtuale, perché entrambe le operazioni seguenti si applicano al client:

  • Il client ha un puntatore a un oggetto IADs1 a interfaccia doppia, che ha una funzione denominata Func0.
  • Visual Basic supporta l'accesso diretto alla tabella virtuale, presupponendo che il tipo di dati sia disponibile tramite la libreria dei tipi.

Nell'esempio di codice successivo, il client ha un puntatore a interfaccia doppia a IADs2 invece di IADs1. Pertanto, IADs2::Func0 viene richiamato usando l'accesso diretto alla tabella virtuale.

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

Anche in questo caso, nell'esempio di codice successivo, sia IADs1 che IADs2 hanno una funzione denominata Func0, ma, in questo caso, il client ha un puntatore a un'interfaccia doppia, IADs0, che non ha una funzione denominata Func0. Pertanto, non è possibile eseguire alcun accesso diretto alla tabella virtuale. IDispatch::GetIDsOfNames e Invoke vengono invece chiamati per richiamare Func0.

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

Considerare questi due casi:

  • IADs1 e IADs2 vengono implementati rispettivamente da due componenti COM, Ext1 e Ext2. Se Ext1 precede Ext2 nel Registro di sistema, viene richiamato IADs1::Func0. Tuttavia, se Ext2 viene prima nel Registro di sistema, viene richiamato IADs2::Func0.
  • Se IADs1 e ADs2 vengono implementati dallo stesso oggetto di estensione, Func0 viene sempre richiamato dai metodi IADsExtension::P rivateGetIDsOfNames e PrivateInvoke dell'estensione.

Lo sviluppatore di estensioni deve determinare come risolvere i conflitti di funzioni o proprietà di interfacce IDispatch diverse con lo stesso nome in un'estensione. L'implementazione dei metodi IADsExtension::P rivateGetIDsOfNames e PrivateInvoke deve risolvere questo conflitto. Ad esempio, se si usa IMyInterface1::Func1 e IMyInterface2::Func1, dove IMyInterface1 e IMyInterface2 sono interfacce IDispatch duali supportate dallo stesso oggetto di estensione. I metodi PrivateGetIDsOfNames e PrivateInvoke devono determinare quale func1 deve sempre essere chiamato.

Lo stesso vale per i DISPID in conflitto in interfacce duali o IDispatch diverse.

Ad esempio, il DISPID di IMyInterface1::Y è 2 nel file imyinterface1.odl o imyinterface1.idl. Il DISPID di IMyInterface2::X è anche 2 in iMyInterface2.odl. IADsExtension::P rivateGetIDsOfNames deve restituire un DISPID univoco, all'interno dell'estensione stessa, per ognuno, anziché restituire lo stesso DISPID per entrambi.

ADSI risolve il primo problema non supportando più interfacce con nomi di funzione o proprietà in conflitto. Risolve il secondo problema aggiungendo un oggetto univoco, che si trova all'interno dello stesso oggetto di estensione, numero di interfaccia ai bit inutilizzati del DISPID.