À l’aide d’une liaison anticipée et liaison tardive dans Automation


Résumé


Comment la liaison à un serveur Automation, beaucoup de choses dans votre programme, tels que les performances, la flexibilité et la facilité de maintenance peut affecter.

Cet article décrit les types de liaison disponible pour les clients Automation et met en évidence les deux côtés de chaque méthode.

Plus d'informations


Automation est un processus dans lequel un composant logiciel communique avec et/ou contrôle un autre composant logiciel à l’aide de modèle COM du Microsoft (Component Object). Il sert de base à la plupart des communications entre composants utilisés dans les langages tels que Visual Basic ou Visual Basic pour Applications et a devenir une partie intégrante de la plupart des programmes.

Historiquement, un objet Automation est un objet qui prend en charge l’interface IDispatch. Cette interface permet aux clients d’appeler des méthodes et des propriétés au moment de l’exécution sans connaître exactement le même objet qu’ils communiquent avec au moment du design ; un processus appelé liaison tardive. Aujourd'hui, toutefois, le terme qu'objet Automation peut être appliqué à n’importe quel objet COM, même ceux qui ne prennent pas en charge IDispatch (et par conséquent ne peuvent pas être tardives). Cet article suppose que l'objet que vous êtes en train d'Automatiser prend en charge les deux méthodes de liaison.

Qu'est-ce qu'une liaison ?

La liaison est un processus de mise en correspondance des appels de fonction écrites par le programmeur pour le code actuel (interne ou externe) qui implémente la fonction. Il est terminé lorsque l’application est compilée, et toutes les fonctions appelées dans le code doivent respecter avant de pouvoir exécuter le code.

Pour comprendre le processus, pensez « liaison » en termes de publication d’un livre. Imaginez que votre code est comme le texte du livre où dans un paragraphe de certain vous avez écrit quelque chose comme « voir page 12, chapitre x pour plus d’informations ». Vous ne savez pas quel est le numéro de page jusqu'à ce que le livre soit terminé, donc avant que le paragraphe puisse être lu, toutes les pages du livre doivent être liés entre elles et le bon numéro de page est inséré dans le paragraphe. Vous attendez que le livre soit "lié" avant de pouvoir référencer toutes les autres parties du livre.

Logiciel de liaison est similaire. Votre code est constitué de parties qui doivent être réunies avant que le code peut être « lue ». La liaison consiste à remplacer les noms de fonction avec des adresses de mémoire (ou d’offsets de mémoire, pour être plus précis) où le code sera « atteindre » lorsque la fonction est appelée. Pour les objets COM, l’adresse est un offset mémoire dans une table de pointeurs (appelé la v-table) détenu par l’objet. Lorsqu’une fonction COM est liée, il est lié par l’intermédiaire de la v-table.

La structure d’un objet COM est simple. Lorsque votre code conserve une référence à un objet, elle conserve un pointeur indirect en haut de la v-table. La v-table est un tableau d’adresses mémoire où chaque entrée est une autre fonction qui peut être appelée sur cet objet. Pour appeler la troisième fonction sur un objet COM, vous "sautez" trois entrées dans la table pour ensuite accéder à l'emplacement mémoire correspondant. Cela exécute le code de la fonction et vous renvoie ensuite sur la prochaine ligne de code à exécuter.


+-[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 | :
: +----------------------------+ :
+................................................+

L’exemple ci-dessus montre ce qui se passe lors de la libération d’un objet COM. Étant donné que tous les objets COM héritent de IUnknown, les trois premières entrées de la table sont les méthodes IUnknown. Lorsque vous avez besoin de libérer un objet, votre code appelle la troisième fonction dans la v-table (IUnknown::Release).

Heureusement, ce travail est effectué par Visual Basic en tâche de fond. Un programmeur Visual Basic, vous avez jamais à traiter directement avec une v-table. Toutefois, cette structure est comment tous les objets COM sont liés, et il est important que vous connaissez afin de comprendre ce que la liaison est.

Liaison anticipée

L’exemple ci-dessus est ce qui est connue dès le début (ou v-table). Pour tous les objets COM, ce type de liaison se placer chaque fois que l’interface IUnknown de l’objet d’un COM est appelée. Mais qu’en est-il des autres fonctions de l’objet ? Comment appeler la méthode Refresh ou sa propriété Parent ? Il s’agit des fonctions personnalisées qui sont généralement spécifiques à un objet. Si leurs emplacements dans la v-table ne peut pas être assurées, comment trouver les adresses de fonction permettant de les appeler ?

La réponse dépend, bien sûr, si vous connaissez à l’avance l’aspect de v-table l’objet. Dans ce cas, vous pouvez exécuter le même processus de liaison anticipée aux méthodes personnalisées de l’objet comme vous l’avez fait à ses méthodes IUnknown. C’est ce que vise généralement par « liaison anticipée. »


Pour utiliser une liaison anticipée sur un objet, vous devez savoir à quoi ressemble sa v-table. Dans Visual Basic, cela en ajoutant une référence à une bibliothèque de types qui décrit toutes les fonctions qui peuvent être appelées sur l’objet, l’objet et son interface (v-table). Une fois cette opération effectuée, vous pouvez déclarer un objet comme étant d’un certain type, puis définir et utiliser cet objet à l’aide de la v-table. Par exemple, si vous souhaitez automatiser Microsoft Office Excel à l’aide de la liaison anticipée, vous ajoutez une référence à la « Microsoft Excel 8.0 Object Library » à partir du projet | Référence de boîte de dialogue et ensuite déclarer votre variable comme étant du type « Excel.Application ». Dès lors, tous les appels à votre variable objet seraient anticipées :
' 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
Cette méthode fonctionne très bien la plupart du temps, mais que se passe-t-il si vous ne connaissez pas l'objet exact que vous utiliserez au moment du design ? Par exemple, que se passe-t-il si vous devez parler à plusieurs versions de Microsoft Excel, ou éventuellement un objet « inconnu » de complètement ?

Liaison tardive

COM inclut IDispatch. Les objets qui implémentent IDispatch sont réputées avoir une dispinterface (si elle est la seule interface qu’ils prennent en charge) ou double (s’ils ont également une interface personnalisée que vous pouvez rapidement lier). Clients qui se lient à IDispatch sont dit être « liaison tardive » car la propriété exacte ou la méthode qu’elles appellent est déterminée au moment de l’exécution à l’aide de méthodes de IDispatch pour les localiser. Pour revenir à l’exemple du carnet de version antérieure, considérez-le comme étant comme une note de bas de page qui vous dirige vers la table des matières où vous devrez « consulter » le numéro de page au « temps de lecture » au lieu d’avoir déjà imprimer il dans le texte.

La magie de l’interface est contrôlée par deux fonctions : GetIDsOfNames et Invoke. La première mappe les noms de fonctions (chaînes) à un identificateur (appelé un dispid) qui représente la fonction. Une fois que vous connaissez l’ID de la fonction que vous voulez appeler, vous pouvez l’appeler à l’aide de la fonction à appeler. Cet écran de l’appel de la méthode est appelé « liaison tardive ».


Encore une fois, dans Visual Basic, la manière dont vous spécifiez la façon dont l’objet est lié est par votre déclaration de l’objet. Si vous déclarez une variable d’objet « Objet » vous sont, en fait, indiquant à Visual Basic d’utiliser IDispatch et sont donc liaison tardive :
' 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
Comme vous pouvez le voir, le reste de votre code est le même. La seule différence entre la liaison anticipée et liaison tardive (en termes de code que vous écrivez) est dans la déclaration de variable.

Il est important de noter que ce qui est « liaison tardive » est la fonction appelée, et non la façon dont elle est appelée. Dans la discussion précédente sur la liaison en général, vous devriez remarquer que IDispatch lui-même est « anticipée : » c'est-à-dire que Visual Basic effectue l’appel pour définir la propriété Visible via une entrée de la v-table (IDispatch::Invoke) comme il le ferait n’importe quel appel COM. L’objet COM lui-même est responsable de la transmission de l’appel à la fonction appropriée pour rendre Excel visible. Cette indirection permet au client de Visual Basic à compiler (qui est, associé à une adresse de fonction valide) mais toujours pas de connaître la fonction exact qui effectue réellement le travail.

Liaison DISPID

Certains Automation les clients (la plupart des sensiblement MFC et Visual Basic 3.0, mais également Visual Basic 5.0 et 6.0 en ce qui concerne les contrôles ActiveX) utilisent un hybride écran de retard de liaison appelée liaison dispid. Si l’objet COM est connu au moment du design, les DISPID pour les fonctions qui sont appelées peuvent être mis en cache et transmis directement à IDispatch::Invoke sans le besoin d’appeler GetIDsOfNames au moment de l’exécution. Cela peut augmenter considérablement les performances, car au lieu d’effectuer deux appels COM par fonction, il vous suffit de créer une.

Une liaison DISPID n’est pas une option, que vous pouvez normalement choisir dans Visual Basic 5.0 ou 6.0. Il est utilisé pour les objets qui sont référencés dans une bibliothèque de types, mais ne contiennent pas d’une interface personnalisée (c'est-à-dire, pour les objets qui ont une dispinterface uniquement) et pour agréger les contrôles ActiveX, mais, en règle générale, Visual Basic utilise la liaison anticipée n’importe où vous utiliseriez normalement liaison DISPID.

Quel type de liaison dois-je utiliser ?

La réponse à cette question dépend autant de la conception de votre projet comme tout autre élément. Microsoft recommande une liaison anticipée dans presque tous les cas. Toutefois, il peut y avoir des raisons pour le choix d’une liaison tardive.

Liaison anticipée est la méthode recommandée. Il est le plus performant, car votre application lie directement à l’adresse de la fonction appelée et il n’existe aucune charge supplémentaire dans une recherche de l’exécution. En fonction de la vitesse d’exécution générale, il est au moins deux fois plus rapide que la liaison tardive.

Liaison anticipée assure également la sécurité de type. Lorsque vous avez une référence à la bibliothèque de types du composant, Visual Basic fournit la prise en charge IntelliSense pour vous aider à coder chaque fonction correctement. Visual Basic vous avertit également si le type de données d’un paramètre ou valeur de retour est incorrect, l’enregistrement de beaucoup de temps lors de l’écriture et débogage du code.

Liaison tardive est encore utile dans les situations où l’interface exacte d’un objet n’est pas connu au moment du design. Si votre application tente de communiquer avec plusieurs serveurs inconnus ou a besoin pour appeler des fonctions par son nom (à l’aide de la fonction Visual Basic 6.0 CallByName par exemple) vous devez utiliser une liaison tardive. Liaison tardive est également utile pour résoudre des problèmes de compatibilité entre plusieurs versions d’un composant qui a incorrectement modifié ou adapter son interface entre les versions.

Les avantages offerts à liaison anticipée rendent le meilleur choix possible.

Maintenir la compatibilité entre plusieurs versions

Si vous utilisez un composant que vous ne pas redistribuer avec votre package d’installation et ne peut pas être assuré de la version exacte que vous communiquera au moment de l’exécution, vous faites attention à liaison anticipée à une interface qui est compatible avec tous les versions du composant, ou, dans certains cas, utilisent la liaison tardive pour appeler une méthode qui peut exister dans une version particulière et échouer correctement si cette méthode n’est pas présente dans la version installée sur le système client.

Un bon exemple de tels serveurs COM fournissent des applications de Microsoft Office. Les applications Office développera généralement leurs interfaces pour ajouter de nouvelles fonctionnalités ou des lacunes précédents corrects entre les versions. Si vous avez besoin automatiser une application Office, il est recommandé que vous liez au début de la version la plus récente du produit que vous comptez peut être installé sur votre système de client. Par exemple, si vous avez besoin être en mesure d’automatiser Excel 95, Excel 97, Excel 2000 et Excel 2002, vous devez utiliser la bibliothèque de types pour Excel 95 (XL5en32.olb) pour assurer la compatibilité avec toutes les versions de trois.

Les applications Office montrent également que les modèles d’objet avec des interfaces doubles grands peuvent en pâtir limitations dans le marshaling sur certaines plates-formes. Pour que votre code sur toutes les plates-formes les mieux adaptées, utiliser IDispatch.
Pour plus d’informations sur la gestion de compatibilité lorsque vous travaillez avec les applications Office, cliquez sur le numéro ci-dessous pour afficher l’article correspondant dans la Base de connaissances Microsoft :

247579 une liaison DISPID de l’utiliser pour automatiser des applications Office chaque fois que possible

Références


Pour plus d’informations sur COM, v-tables et à l’aide d’Automation, consultez les ouvrages suivants :
Rogerson, Dale, à l’intérieur de COM, MSPRESS, ISBN : 1-57231-349-8.

Curland, Matt, avancées de Visual Basic 6, DevelopMentor, 0201707128.