Distributed COM
Cet article décrit comment un programme client peut invoquer un objet COM situé sur une autre machine au moyen de DCOM (extension distribué du modèle objet COM Microsoft), et quels sont les paramétrages à effectuer de part et d'autre.
Si le serveur COM est de type automation, nous montrerons que le client n'a besoin de connaître que le nom de la machine distante et l'identificateur de la classe, sans aucun paramétrage particulier.

Cet article est d'avantage destiné à l'environnement Delphi, mais les principes utilisés s'appliquent à tout environnement de développement supportant COM. Nous préciserons à chaque fois ce qui est spécifique à Delphi.


Serveur COM

Nous partirons d'un serveur hors processus (exécutable) comprenant un objet automation (classe COM supportant l'interface IDispatch). Dans l'EDI Delphi, il suffit de créer une nouvelle application et d'y ajouter un objet automation au moyen de l'assistant adéquat.
Supposons que vous ayez saisi "Service" comme nom de CoClass.



L'éditeur de la bibliothèque de types vous permettra de compléter votre interface IService héritée de IDispatch déclarée dans l'unité générée par l'assistant. Cette unité, dont le nom est celui du projet suivi de "_TLB", comprend la classe utilitaire CoService définissant deux fonctions de classe destinées à instancier votre classe COM en renvoyant un pointeur d'interface ayant le type IService.
La première de ces méthodes, "Create", crée un objet local, la seconde, "CreateRemote" un objet distant sur la machine dont le nom est passé en paramètre. Au final, se sont respectivement les fonctions de l'API Windows CoCreateInstance et CoCreateInstanceEx qui sont appelées de manière interne.


Recensement du serveur

Le recensement du serveur peut être fait depuis Delphi, ou bien en démarrant l'application (auto-recensement), ou encore en démarrant l'application avec l'argument /regserver.
Dans le cas d'un objet COM en processus (DLL), l'utilitaire Microsort regsvr32 peut être appelé avec le chemin complet de la dll.


Appel distant du client

L'unité représentant en Pascal Objet la bibliothèque de types de votre serveur (unité projet_TLB) peut être réutilisée par une application cliente s'exécutant sur une autre machine. De cette manière, votre code s'appuie sur l'utilisation du pointeur d'interface IService (liaison précoce). Par exemple :

var
  Service: IService;
begin
  Service := CoService.CreateRemote('HOSTNAME');
  ... // faire quelque chose avec le pointeur d'interface IService
end;

Dans le code ci-dessus l'objet Service est créé sur la machine distante 'HOSTNAME'. Par défaut tous les chemins UNC, tels que \\serveur ou serveur, et les noms DNS, tels que serveur.com ou 144.19.56.38, sont permis.
La fonction CoCreateInstanceEx, appelée de manière interne par CreateRemote, ne recherche pas dans la base de registres du client le CLSID désiré (GUID de classe de l'objet Service), mais contacte plutôt le SCM qui réside sur la machine distante spécifiée et lui demande de rechercher le base de registres de ce serveur.
Avec cette technique, il est nécessaire soit de recenser l'activeX sur la machine cliente, ce qui oblige à avoir une copie de votre exécutable sur cette machine, soit de recenser uniquement la bibliothèque de types.
Votre projet comprend cette bibliothèque de types sous forme de ressource Windows incluse dans l'exécutable et sous forme de fichier projet.tlb. L'utilitaire Borland tregsvr.exe, situé normalement dans le répertoire Bin de Delphi vous permettra de recenser le fichier projet.tlb.
Il suffirait à un environnement de développement compatible COM d'importer cette bibliothèque de types pour obtenir les méthodes et propriétés de l'objet Service.

Il existe un moyen de se passer de tout paramétrage sur le poste client, du fait que le serveur supporte l'interface IDispatch.
En pascal objet nous utiliserions un variant de la manière suivante :

const
CLASS_MonService: TGUID = '{F845A45F-1A3C-4866-B44F-F92FB491015B}';
var
  Service: Variant;
begin
  Service := CreateRemoteComObject('HOSTNAME', CLASS_MonService) as IDispatch;
  ... // faire quelque chose avec Service
end;

La seule contrainte est de connaître le CLSID de la classe COM à invoquer sur la machine distante. Dans l'unité projet_TLB, ce GUID apparaît comme constante dans la partie interface de l'unité.
Le code du programme client utiliserait donc la liaison tardive (pas de vérification à la compilation) comme pour n'importe quel autre objet automation.


Appel local, mais distant !

Pour les applications instanciant des objets COM locaux, il est toujours possible d'utiliser DCOM sans devoir changer une seule ligne de code. Moyennant des modifications de la base de registres concernant les classes de votre serveur, vous pouvez spécifier sur quelle machine doit être instancié un objet COM. Pour vous y aider, utilisez l'utilitaire de configuration DCOM dcomcnfg.exe (voir la rubrique Ressources plus loin). Après avoir sélectionné "Service objet" comme application, cliquez sur le bouton Propriétés. Dans la boîte de dialogue qui s'ouvre vous pouvez alors sélectionner le nom de la machine sur laquelle instancier votre activeX.




Ressources

Utilisation de l'utilitaire dcomcnfg
Description de CoCreateInstanceEx

Sommaire

Serveur COM
Recensement du serveur
Appel distant du client
Appel local, mais distant !
Ressources

Début

Copyright © 2003 OBJECT-EVERYWHERE. Tous droits réservés | Bertrand Goetzmann