Utilizar enlace anticipado y enlace en tiempo de ejecución en automatización

Seleccione idioma Seleccione idioma
Id. de artículo: 245115 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

La forma de enlazarse a un servidor de automatización puede afectar a muchas cosas en un programa, como el rendimiento, la flexibilidad y el mantenimiento.

En este artículo se explican los tipos de enlace disponible en los clientes de Automatización y se valoran ambos lados de cada método.

Más información

Automatización es un proceso en el cual un componente de software se comunica con y/o controla otro componente de software utilizando el Modelo de objetos componentes (COM) de Microsoft. Es la base de la mayoría de la comunicación entre componentes utilizada en lenguajes como Visual Basic o Visual Basic para Aplicaciones y se ha convertido en una parte normal de la mayoría de los programas.

Históricamente, un objeto de Automatización es cualquier objeto que admite la interfaz IDispatch. Esta interfaz permite a los clientes llamar a métodos y propiedades en tiempo de ejecución sin tener que conocer el objeto exacto con el que se están comunicando en tiempo de diseño; un proceso denominado enlace en tiempo de ejecución. Sin embargo, hoy en día el término objeto de Automatización puede aplicarse virtualmente a cualquier objeto COM, incluso a aquellos que no admiten IDispatch (y, por tanto, no se pueden enlazar en tiempo de ejecución). En este artículo se supone que el objeto que está automatizando admite ambos métodos de enlace.

Qué es el enlace

El enlace es un proceso de hacer coincidir llamadas a funciones escritas por el programador con el código real (interno o externo) que implementa la función. Se realiza cuando se compila la aplicación y todas las funciones llamadas en el código deben enlazarse antes de que se pueda ejecutar el código.

Para entender el proceso, piense en el "enlace" como la publicación de un libro. Suponga que el código es como el texto del libro donde en cierto párrafo ha escrito algo así como "consulte el capítulo 12, página x para obtener más detalles". No sabe cuál es el número de página hasta que el libro está terminado, por lo que antes de poder leer el párrafo como está previsto, se deben enlazar todas las páginas del libro e insertar el número de página correcto en el párrafo. Espera que el libro esté "enlazado" antes de poder hacer referencia a otras partes del libro.

El enlace de software es similar. El código consta de partes que hay que agrupar antes de que se pueda "leer" el código. El enlace es el acto de reemplazar nombres de función con direcciones de memoria (o desplazamientos de memoria, para ser más precisos) a las que "saltará" el código cuando se llame a la función. En el caso de los objetos COM, la dirección es un desplazamiento de memoria en una tabla de punteros (denominada tabla v) contenida en el objeto. Cuando se enlaza una función COM, se enlaza a través de la tabla v.

La estructura de un objeto COM es sencilla. Cuando el código contiene una referencia a un objeto, mantiene un puntero indirecto a la parte superior de la tabla v. La tabla v es una matriz de direcciones de memoria donde cada entrada es una función diferente a la que se puede llamar en ese objeto. Para llamar a la tercera función de un objeto COM, salta tres entradas hacia abajo en la tabla y, a continuación, salta a la ubicación de memoria proporcionada allí. Eso ejecuta el código de la función y, cuando se completa, vuelve preparado para ejecutar la línea siguiente de código.

+-[Código]------------+  +.........................................[Objeto COM]...+
|                   |  : +-------------------+                                    :
|Set obj = Nothing -|--->| puntero de objeto |                                    :
|                   |  : +-|-----------------+                                    :
+-------------------+  :   |   +----------------------+                           :
                       :   +-->| puntero a la tabla v |                           :
                       :       +--|-------------------+                           :
                       :          |                                               :
                       :          |  +--------------------------------------+     :
                       :  (3ª)    |  | Puntero de dirección de la función 1 |     :
                       :(Desplaza |  +--------------------------------------+     :
                       : zamiento)|  | Puntero de dirección de la función 2 |     :
                       :          |  +--------------------------------------+     :
                       :          +->| Puntero de dirección de la función 3 |     :
                       :             +--------------------------------------+     :
                       +..........................................................+

				
El ejemplo anterior muestra lo que ocurre al liberar un objeto COM. Puesto que todos los objetos COM heredan de IUnknown, las tres primeras entradas de la tabla son los métodos para IUnknown. Cuando necesita liberar un objeto, el código llama a la tercera función de la tabla v (IUnknown::Release).

Afortunadamente, Visual Basic lo hace en segundo plano. Como programador de Visual Basic, nunca tiene que tratar directamente con una tabla v. Pero esta estructura es cómo se enlazan todos los objetos COM y es importante que esté familiarizado con ella para entender qué es el enlace.

Enlace anticipado

El ejemplo anterior es lo que se conoce como enlace anticipado (o tabla v). Para todos los objetos COM, esta forma de enlace tiene lugar siempre que se llama a la interfaz IUnknown de un objeto COM. Pero ¿qué ocurre con las otras funciones del objeto? ¿Cómo llama a su método Refresh o a su propiedad Parent? Se trata de funciones personalizadas que suelen ser únicas de un objeto. Si no se puede suponer sus ubicaciones en la tabla v, ¿cómo busca las direcciones de función necesarias para llamarlas?

La respuesta, por supuesto, depende de si conoce de antemano o no la apariencia de la tabla v del objeto. En caso afirmativo, puede realizar el mismo proceso de enlace anticipado en los métodos personalizados del objeto como hacía con sus métodos IUnknown. Esto es lo que se conoce generalmente como "enlace anticipado".

Para utilizar el enlace anticipado en un objeto, necesita conocer la apariencia de su tabla v. En Visual Basic, puede hacerlo agregando una referencia a una biblioteca de tipos que describe el objeto, su interfaz (tabla v) y todas las funciones a las que se puede llamar en el objeto. Una vez hecho esto, puede declarar un objeto como que es de cierto tipo y, a continuación, establecer y utilizar ese objeto utilizando la tabla v. Por ejemplo, si deseara automatizar Microsoft Office Excel utilizando enlace anticipado, agregaría una referencia a la "Biblioteca de objetos de Microsoft Excel 8.0" en el cuadro de diálogo Proyecto|Referencias y, a continuación, declararía su variable como del tipo "Excel.Application". A partir de entonces, todas las llamadas realizadas a la variable del objeto estarían enlazadas anticipadamente:
' 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 bien la mayoría de las veces, pero ¿qué ocurre si no conoce el objeto exacto que utilizará en tiempo de diseño? Por ejemplo, ¿y si necesita hablar con varias versiones de Excel o posiblemente con un objeto "desconocido"?

Enlace en tiempo de ejecución

COM incluye IDispatch. Se dice que los objetos que implementan IDispatch tienen una interfaz de envíos (si es la única interfaz que admiten) o una interfaz dual (si tienen también una interfaz personalizada a la que se puede enlazar anticipadamente). Se dice que los clientes que se enlazan a IDispatch están "enlazados en tiempo de ejecución" porque la propiedad o el método exacto al que llaman se determina en tiempo de ejecución utilizando los métodos de IDispatch. Volviendo al ejemplo del libro anterior, piense en él como una nota al pie que le dirige a la tabla de contenido donde tiene que "buscar" el número de página en el "momento de la lectura" en lugar de tenerlo impreso en el texto.

Dos funciones controlan la magia de la interfaz: GetIDsOfNames e Invoke. La primera asigna nombres de función (cadenas) a un identificador (denominado dispid) que representa la función. Cuando conoce el Id. para la función a la que desea llamar, puede llamarla utilizando la función Invoke. Esta forma de invocación de métodos se denomina "enlace en tiempo de ejecución".

De nuevo, en Visual Basic la manera de especificar cómo se enlaza el objeto es por su declaración de objeto. Si declara una variable de objeto como "Object", está indicando a Visual Basic que debe utilizar IDispatch y, por tanto, se utiliza el enlace en tiempo de ejecución:
' 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
				
Cuando puede ver, el resto del código es el mismo. La única diferencia entre el enlace anticipado y el enlace en tiempo de ejecución (en lo que se refiere al código que escribe) está en la declaración de variables.

Es importante tener en cuenta que lo que se "enlaza en tiempo de ejecución" es la función a la que se llama y no la manera en que se llama. De la explicación anterior del enlace en general se desprende que la propia interfaz IDispatch tiene "enlace anticipado": es decir, que Visual Basic realiza la llamada para establecer la propiedad Visible mediante una entrada de la tabla v (IDispatch::Invoke) como haría en cualquier llamada COM. El propio objeto COM es responsable de reenviar la llamada a la función correcta para hacer que Excel sea visible. Este direccionamiento indirecto permite compilar el cliente de Visual Basic (es decir, enlazarlo a una dirección de función válida) pero todavía no se conoce la función exacta que hará realmente el trabajo.

Enlace Dispid

Algunos clientes de Automatización (principalmente MFC y Visual Basic 3.0, pero también Visual Basic 5.0 y 6.0 con respecto a los controles ActiveX) utilizan una forma híbrida de enlace en tiempo de compilación denominado enlace dispid. Si se conoce el objeto COM en tiempo de diseño, los dispid para las funciones a las que se llama se pueden almacenar en caché y pasar directamente a IDispatch::Invoke sin necesidad de llamar en tiempo de ejecución a GetIDsOfNames. Esto puede mejorar considerablemente el rendimiento, ya que en lugar de realizar dos llamadas COM por función sólo necesita realizar una.

El enlace dispid no es una opción que elija normalmente en Visual Basic 5.0 ó 6.0. Se utiliza para los objetos a los que se hace referencia en una biblioteca de tipos pero que no contienen una interfaz personalizada (es decir, para los objetos que sólo tienen una interfaz de envíos) y para los controles ActiveX agregados pero, en general, Visual Basic utiliza el enlace anticipado cuando normalmente utilizaría el enlace dispid.

¿Qué forma de enlace debe utilizar?

La respuesta a esta pregunta depende principalmente del diseño del proyecto. Microsoft recomienda el enlace anticipado en la mayoría de los casos. Sin embargo, puede haber razones para elegir el enlace en tiempo de ejecución.

El enlace anticipado es el método preferido. Es el que ofrece mayor rendimiento, ya que la aplicación se enlaza directamente a la dirección de la función a la que se llama y no hay ninguna sobrecarga adicional para realizar una búsqueda en tiempo de ejecución. Por lo que se refiere a la velocidad de ejecución global, es al menos dos veces tan rápido como el enlace en tiempo de ejecución.

El enlace anticipado también proporciona seguridad de tipos. Cuando tiene un conjunto de referencias a la biblioteca de tipos del componente, Visual Basic proporciona compatibilidad con IntelliSense para ayudarle a codificar correctamente cada función. Visual Basic también le avisa si el tipo de datos de un parámetro o de un valor devuelto es incorrecto, lo que ahorra mucho tiempo a la hora de escribir y depurar código.

El enlace en tiempo de ejecución sigue siendo útil en aquellas situaciones en las que la interfaz exacta de un objeto no se conoce en tiempo de diseño. Si su aplicación desea hablar con varios servidores desconocidos o necesita invocar funciones por nombre (utilizando por ejemplo la función CallByName de Visual Basic 6.0), tiene que utilizar el enlace en tiempo de ejecución. El enlace en tiempo de ejecución también es útil para evitar problemas de compatibilidad entre varias versiones de un componente que ha modificado o adaptado incorrectamente su interfaz entre las distintas versiones.

Las ventajas del enlace anticipado hacen que sea la mejor opción siempre que sea posible.

Mantener la compatibilidad entre varias versiones

Si va a utilizar un componente que no redistribuye con su paquete de instalación, y no puede saber con seguridad la versión exacta con la que se comunicará en tiempo de ejecución, debe prestar especial atención al enlace anticipado con una interfaz que sea compatible con todas las versiones del componente o (en algunos casos) utilizar el enlace en tiempo de ejecución para llamar a un método que puede existir en una versión determinada y no producirse correctamente si ese método no está presente en la versión instalada en el sistema cliente.

Las aplicaciones de Microsoft Office constituyen un buen ejemplo de esos servidores COM. Las aplicaciones de Office normalmente expandirán sus interfaces para agregar nueva funcionalidad o corregir limitaciones anteriores entre las versiones. Si necesita automatizar una aplicación de Office, se recomienda que utilice el enlace anticipado con la versión anterior del producto que espera podría estar instalada en el sistema del cliente. Por ejemplo, si necesita poder automatizar Excel 95, Excel 97, Excel 2000 y Excel 2002, debe utilizar la biblioteca de tipos para Excel 95 (XL5en32.olb) con el fin de mantener la compatibilidad con las tres versiones.

Las aplicaciones de Office también muestran que los modelos de objetos con interfaces duales grandes pueden sufrir limitaciones al serializar en algunas plataformas. Para que el código funcione mejor en todas las plataformas, utilice IDispatch. Para obtener más información acerca de cómo mantener la compatibilidad cuando se trabaja con aplicaciones de Office, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
247579 Utilizar siempre que se pueda el enlace DISPID para automatizar aplicaciones de Office

Referencias

Para obtener más información acerca de COM, las tablas v y el uso de Automatización, consulte los libros siguientes:
Rogerson, Dale, Inside COM, MSPRESS, ISBN: 1-57231-349-8.

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

Propiedades

Id. de artículo: 245115 - Última revisión: jueves, 21 de febrero de 2008 - Versión: 7.1
La información de este artículo se refiere 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 Edición empresarial
Palabras clave: 
kbinfo kbautomation KB245115

Enviar comentarios

 

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