Resolução de conflitos de nome de função/propriedade em automação em extensões

Neste tópico, "object" indica o objeto, como um todo, como um cliente ADSI o visualiza. Ou seja, ADSI e todas as suas extensões.

Mesmo nome de função com os mesmos parâmetros

Se duas ou mais interfaces IDispatch duplas em um objeto oferecerem suporte a uma propriedade ou método de mesmo nome, por exemplo, Func1, a invocação será determinada usando os seguintes critérios. Se o cliente tiver um ponteiro para uma das interfaces duplas que oferecem suporte a um método chamado Func1 e se o ambiente de automação oferecer suporte ao acesso vtable, o Func1 será chamado diretamente por meio do acesso ADSI vtable.

Se uma das condições acima for false, IDispatch::GetIDsOfNames e IDispatch::Invoke serão chamados para invocar Func1.

Para obter mais informações e uma breve explicação sobre como um cliente pode adicionar um ponteiro a uma interface dupla e uma descrição dos tipos de ambientes que oferecem suporte ao acesso vtable, consulte Late Binding versus Vtable Access no modelo de extensão ADSI.

Como todos os objetos de extensão redirecionam as funções IDispatch de volta para o agregador, o agregador controla qual Func1 é invocado. As regras são:

  • Se alguma interface, e haverá apenas uma, se houver, no agregador (ADSI) suporta uma função chamada Func1, o agregador invoca seu próprio Func1.
  • Caso contrário, o agregador passa por cada uma de suas extensões, na ordem listada no registro, e encontra a primeira extensão que implementa uma função chamada Func1. É possível, mas improvável, que várias interfaces IDispatch duplas nesta primeira extensão tenham uma função chamada Func1. A extensão deve determinar qual Func1 sempre deve ser invocado em Automação.

O mesmo nome de função com parâmetros diferentes

A seção anterior discutiu como resolver conflitos de nome de função, ou seja, nomes de função que têm o mesmo nome de função e a mesma lista de parâmetros, como número, tipo e ordem, quando isso ocorre na automação. E se duas funções tiverem o mesmo nome, mas parâmetros diferentes? Se um cliente ADSI invocar a função usando IDispatch::GetIDsOfNames sem usar vários nomes para especificar os parâmetros, o modelo de extensão ADSI não poderá desambiguar as funções. Com base no esquema de resolução discutido acima, a primeira extensão no registro que suporta essa função por meio de uma de suas interfaces tem sua versão dessa função invocada, e a chamada pode falhar ou produzir resultados incorretos.

Por exemplo:

  • Extn1 (primeiro no registro na classe CA – prioridade mais alta) suporta IInterface1.
  • Extn2 (terceiro no registro na classe CA – prioridade mais baixa) suporta IInterface2.
  • IInterface1 suporta Method1(int param1, int param2).
  • IInterface2 suporta Method1(int param1).

Um cliente ADSI tem um ponteiro de interface IDispatch para um objeto de CA de classe. Ele deseja invocar IInterface2::Method1. Se o cliente chamar "pDispatch-GetIDsOfNames>(IID_NULL, rgszNames, 1, MY_LCID, rgDispId)" apenas armazenando o nome da função "Method1" em rgszNames[0], então IInterface1::Method1 em vez do desejado IInterface2::Method1 será invocado e a função falhará porque o número de parâmetros é diferente.

Para minimizar esse problema, os desenvolvedores de extensão podem prefixar seus nomes de função com seus próprios identificadores específicos e evitar designs de interface que usam funções do mesmo nome, mas parâmetros diferentes.

Se ocorrer um conflito de nome, os clientes ADSI poderão evitar o problema por meio do acesso direto vtable se a interface for uma interface dupla. Se o acesso vtable direto não for possível, os clientes ADSI devem chamar IDispatch::GetIDsOfNames com vários nomes, especificando os nomes de função, bem como os parâmetros na matriz rgszNames descritos anteriormente.

Visual Basic 5 não chama a função IDispatch::GetIDsOfNames com vários nomes. Ou seja, ele passa apenas o nome da função para GetIDsOfNames, mas não argumentos. No entanto, o Visual Basic 5 permite que os usuários invoquem uma função por acesso vtable direto, em vez de invocar a função IDispatch::GetIDsOfNames se a interface for uma interface dupla. Os desenvolvedores devem usar o acesso vtable direto, se possível.

Para obter mais informações sobre a resolução de conflitos de nome, consulte Exemplo para resolver conflitos de nome de função.