Utilização da associação inicial e associação tardia na Automação

Traduções deste artigo Traduções deste artigo
ID do artigo: 245115 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

Como a associação a um servidor de Automação pode afetar muitos fatores no seu programa, tais como o desempenho, a flexibilidade e a manutenção.

Este artigo explica os tipos de associações disponíveis para clientes de Automação e avalia ambos os lados de cada método.

Mais Informações

Automação é um processo no qual um componente de software comunica-se com e/ou controla outro componente de software usando o modelo COM (Modelo de Objeto Componente) da Microsoft. Ele é a base para a maioria das comunicações entre componentes usadas em linguagens como Visual Basic ou Visual Basic for Applications e tornou-se uma parte comum da maioria dos programas.

Historicamente, um objeto de Automação é qualquer objeto que suporta a interface IDispatch. Essa interface permite que os clientes invoquem métodos e propriedades no momento da execução sem saber exatamente com qual o objeto estão se comunicando no tempo de criação; este processo é chamado de associação tardia. Hoje, porém, o termo Objeto de Automação pode ser aplicado virtualmente a qualquer objeto COM, mesmo os que não suportam IDispatch (e por tanto não podem fazer associação tardia). Este artigo presume que o objeto que está você automatizando suporta ambos os métodos de associação.

O que é associação?

Associação é um processo de chamadas de função correspondente desenvolvido pelo programador para o código real (interno ou externo) que implementa a função. Ele é feito quando o aplicativo é compilado e todas as funções chamadas no código são associadas antes da execução do código.

Para entender o processo, pense em "associação" como a publicação de um livro. Imagine que seu código é como o texto do livro onde em um determinado parágrafo você escreveu algo como "consulte o capítulo 12, página x, para obter mais detalhes". Você não sabe qual é o número da página até que o livro seja concluído, então antes que o parágrafo possa ser lido conforme o desejado, todas as páginas dele devem ser agrupadas e o número correto da página inserido no parágrafo. Você espera que o livro seja "agrupado" antes de poder fazer referência às outras partes do livro.

O software de associação é semelhante. Seu código é feito de partes que precisam ser agrupadas antes que ele possa ser "lido". Associar é o ato de substituir nomes de função por endereços de memória (ou deslocamentos de memória, para ser mais preciso) para onde o código "irá" quando a função for chamada. Para os objetos COM, o endereço é um deslocamento de memória em uma tabela de ponteiros (chamada de v-table) manipulada pelo objeto. Quando uma função COM é associada, a associação é feita através da v-table.

A estrutura de um objeto COM é simples. Quando seu código faz referência a um objeto, ele referencia um ponteiro indireto para a parte superior da v-table. A v-table é uma matriz de endereços de memória onde cada entrada é uma função diferente que pode ser chamada naquele objeto. Para chamar a terceira função em um objeto COM, você retorna três entradas na tabela e vai até o local da memória determinado lá. Isso executa o código para a função e, quando concluído, deixa você pronto para executar a próxima linha do código.

+-[Code]------------+  +.................................[COM Object]...+
|                   |  : +-------------+                                :
|Set obj = Nothing -|--->| obj pointer |                                :
|                   |  : +-|-----------+                                :
+-------------------+  :   |   +-----------------+                      :
                       :   +-->| v-table pointer |                      :
                       :       +--|--------------+                      :
                       :          |                                     :
                       :          |  +----------------------------+     :
                       :  (3rd)   |  | Function 1 Address pointer |     :
                       : (Offset) |  +----------------------------+     :
                       :          |  | Function 2 Address pointer |     :
                       :          |  +----------------------------+     :
                       :          +->| Function 3 Address pointer |     :
                       :             +----------------------------+     :
                       +................................................+

				
O exemplo acima mostra o que acontece ao liberar um objeto COM. Como todos os objetos COM herdam de IUnknown, as três primeiras entradas na tabela são os métodos para IUnknown. Quando você precisar liberar um objeto, seu código chamará a terceira função na v-table (IUnknown::Release).

Felizmente, este trabalho é feito pelo Visual Basic. Como um programador de Visual Basic, você nunca irá precisar lidar diretamente com uma v-table. Mas, essa estrutura é como todos os objetos COM são associados, e é importante que você esteja familiarizado com ele para entender o que é uma associação.

Associação inicial

O exemplo acima é conhecido como associação inicial (ou v-table). Para todos os objetos COM, esta forma de associação acontece sempre que uma interface IUnknown de um objeto COM é chamada. Mas e as outras funções do objeto? Como você chama seu método de Atualização ou sua propriedade Parent? Essas são funções padrão normalmente exclusivas para um objeto. Se os seus locais na v-table não puderem ser assumidos, como descobrir os endereços de função necessários para chamá-los?

A resposta, claro, depende se você conhece ou não antecipadamente qual a aparência da v-table do objeto. Se você conhece, será possível executar o mesmo processo de associação inicial para os métodos padrão do objeto, assim como foi feito para seus métodos IUnknown. Geralmente, isso é chamado de "associação inicial".

Para usar a associação inicial em um objeto, é preciso conhecer a aparência da sua v-table. No Visual Basic, é possível fazer isso adicionando uma referência a uma biblioteca de tipos que descreve o objeto, a sua interface (v-table) e todas as funções que podem ser chamadas no objeto. Depois disso, é possível declarar um objeto como um tipo determinado, definir e utilizar o objeto usando a v-table. Por exemplo, se você deseja automatizar o Microsoft Office Excel usando a associação inicial, deverá adicionar uma referência ao "Microsoft Excel 8.0 Object Library" da caixa de diálogo Project|References e declarar sua variável como sendo do tipo "Excel.Application". A partir daí, todas as chamadas feitas para a sua variável de objeto farão associação inicial:
' Set reference to 'Microsoft Excel 8.0 Object Library' in
' the Project|References dialog (or Tools|References for VB4 or VBA).

' Declare the object as an early-bound object
  Dim oExcel As Excel.Application

  Set oExcel = CreateObject("Excel.Application")

' The Visible property is called via the v-table
  oExcel.Visible = True
				
Este método funciona muito bem na maior parte do tempo, mas e se você não conhecer o objeto exato que irá usar no tempo de criação? Por exemplo, e se você precisar se comunicar com várias versões do Excel ou possivelmente com um objeto "desconhecido" ao mesmo tempo?

Associação tardia

O COM inclui IDispatch. Os objetos que implementam a interface IDispatch são conhecidos por terem uma dispinterface (se for a única interface suportada) ou uma interface dupla (se também tiverem uma interface padrão à qual é possível fazer uma associação inicial). Os clientes que fazem uma associação tardia com a interface IDispatch são conhecidos como "associados tardiamente", pois a propriedade ou método exato que estão chamando é determinado no momento da execução usando os métodos de IDispatch para localizá-los. Voltando ao exemplo do livro, pense nisso como sendo uma nota de rodapé que direciona você para o índice onde precisa procurar o número da página no "momento da leitura", em vez de o número já estar impresso no texto.

A magia da interface é controlada por duas funções: GetIDsOfNames e Invoke. A primeira mapeia os nomes de função (seqüências) para um identificador (chamado de dispid) que representa a função. Depois de conhecer o identificador (ID) para a função que você deseja chamar, é possível chamá-la usando a função Invoke. Isto forma a invocação de método chamada de "associação tardia".

Novamente, no Visual Basic você especifica como o objeto é associado pela declaração do seu objeto. Se você declarar uma variável de objeto como "Object", na verdade, você estará dizendo para o Visual Basic usar a interface IDispatch e consequentemente a associação tardia:
' No reference to a type library is needed to use late binding.
' As long as the object supports IDispatch, the method can 
' be dynamically located and invoked at run-time.

' Declare the object as a late-bound object
  Dim oExcel As Object

  Set oExcel = CreateObject("Excel.Application")

' The Visible property is called via IDispatch
  oExcel.Visible = True
				
Como você pode ver, o resto do seu código é o mesmo. A única diferença entre a associação inicial e a associação tardia (em termos do código gravado) está na declaração da variável.

É importante observar que "associação tardia" é a função que está sendo chamada e não a forma como ela é chamada. Partindo da discussão anterior sobre associação em geral, você observa que a própria interface IDispatch usa a "associação inicial". Ou seja, o Visual Basic faz a chamada para definir a propriedade Visible através de uma entrada de v-table (IDispatch::Invoke) como faria com qualquer chamada COM. O próprio objeto COM é responsável pelo encaminhamento da chamada até a função correta para tornar o Excel visível. Essa manobra indireta permite que o Visual Basic client seja compilado (ou seja, associado a um endereço de função válido), mas ainda não conheça a função exata que irá realmente fazer o trabalho.

Associação dispid

Alguns clientes de Automação (a maioria MFC e Visual Basic 3.0, mas também Visual Basic 5.0 e 6.0 referente aos controles ActiveX) usam uma forma híbrida de associação tardia chamada de associação dispid. Se o objeto COM for conhecido no tempo de criação, os dispids para as funções chamadas podem ser armazenados em cache e enviados diretamente para IDispatch::Invoke sem a necessidade de chamar GetIDsOfNames no momento da execução. Isto pode melhorar o desempenho, pois em vez de fazer duas chamadas COM por função, será preciso fazer apenas uma.

A associação dispid não é uma opção que você pode normalmente escolher no Visual Basic 5.0 ou 6.0. Ela é usada para objetos referenciados em uma biblioteca de tipos, mas que não contêm uma interface padrão (ou seja, para objetos que tenham apenas uma dispinterface) e para controles ActiveX agregados, mas, em geral, o Visual Basic usa a associação inicial quando você normalmente usaria a associação dispid.

Qual forma de associação usar?

A resposta para essa pergunta depende mais da criação do seu projeto do que de qualquer outro fator. A Microsoft recomenda a associação inicial na maioria dos casos. Porém, existem razões para escolher a associação tardia.

A associação inicial é o método preferido. É o melhor executor porque seu aplicativo associa-se diretamente ao endereço da função que está sendo chamada e não há sobrecarga extra ao fazer uma pesquisa de tempo de execução. Em termos de velocidade de execução total, ela é, pelo menos, duas vezes mais rápida que a associação tardia.

A associação inicial também fornece segurança de tipos. Quando você tem um conjunto de referência para a biblioteca de tipos do componente, o Visual Basic fornece suporte do IntelliSense para ajudá-lo a codificar corretamente cada função. O Visual Basic também avisa a você se o tipo de dados de um parâmetro ou valor de retorno está incorreto, economizando bastante tempo ao gravar ou depurar um código.

A associação tardia ainda é útil em situações onde a interface exata de um objeto não é conhecida no momento da execução. Se o seu aplicativo tenta se comunicar com vários servidores desconhecidos ou precisa invocar funções por nome (usando a função CallByName do Visual Basic 6.0, por exemplo), então você precisará usar a associação tardia. A associação tardia também é útil para solucionar problemas de compatibilidade entre várias versões de um componente que modificou ou adaptou incorretamente sua interface entre as versões.

As vantagens da associação inicial fazem dela a melhor escolha sempre que possível.

Mantendo a compatibilidade entre várias versões

Se você usar um componente que não é redistribuído com seu pacote de configurações e não pode ser garantido para a versão exata com a qual irá se comunicar no momento da execução, será necessário ter especial atenção à associação inicial de uma interface compatível com todas as versões do componente ou (em alguns casos) usar a associação tardia para chamar um método que pode existir em uma versão específica e normalmente falhar se o método não estiver presente na versão instalada no sistema cliente.

Os aplicativos do Microsoft Office oferecem um bom exemplo de tais servidores COM. Os aplicativos do Office irão normalmente expandir suas interfaces para adicionar nova funcionalidade ou corrigir deficiências entre as versões. Se você precisa automatizar um aplicativo do Office, é recomendável que faça uma associação inicial na versão mais recente do produto que espera ser instalado no sistema do seu cliente. Por exemplo, se você precisa estar apto para automatizar o Excel 95, o Excel 97, o Excel 2000 e o Excel 2002, deverá usar a biblioteca de tipos para o Excel 95 (XL5en32.olb) para manter a compatibilidade com todas as três versões.

Os aplicativos do Office também demonstram que os modelos de objeto com grandes interfaces duplas podem sofrer para controlar algumas plataformas. Para que seu código funcione melhor em todas as plataformas, use a interface IDispatch. Para obter informações sobre como manter a compatibilidade ao trabalhar com aplicativos do Office, clique no número do artigo abaixo para exibir o artigo na Base de Dados de Conhecimento Microsoft:
247579 Utilização da a associação DISPID para automatizar aplicativos do Office sempre que possível

Referências

Para obter mais informações sobre COM, v-tables e o uso de Automação, consulte os seguintes livros:
Rogerson, Dale, Inside COM, MSPRESS, ISBN: 1-57231-349-8.

Curland, Matt, Advanced Visual Basic 6, DevelopMentor, 0201707128.

Propriedades

ID do artigo: 245115 - Última revisão: sexta-feira, 28 de dezembro de 2007 - Revisão: 7.1
A informação contida neste artigo aplica-se a:
  • Microsoft Office Ultimate 2007
  • Microsoft Office Enterprise 2007
  • Microsoft Office Professional 2007
  • Microsoft Office Professional Plus 2007
  • Microsoft Office Standard 2007
  • Microsoft Office Home and Student 2007
  • Microsoft Office Basic 2007
  • Microsoft Office Standard Edition 2003
  • Microsoft Office XP Developer Edition
  • Microsoft Office 2000 Developer Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Enterprise Edition
Palavras-chave: 
kbinfo kbautomation KB245115

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com