IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Appel DCOM dynamique - sans type library


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2002
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 22
    Points : 12
    Points
    12
    Par défaut Appel DCOM dynamique - sans type library
    Bonjour,

    Je cherche une méthode permettant d'appeler un composant DCOM sans connaissance de sa type library, par un appel complètement dynamique comme on peut le faire avec la méthode Invoke d'un objet OLE.

    Le but est de pouvoir, à partir d'une appli Delphi win32, appeler n'importe quel composant DCOM en fournissant en paramètre: le nom de serveur, le GUID, les nombres et types de paramètres. L'appli n'a pas connaissance au préalable de ces paramètres (donc pas dispo lors de la compilation: pas d'import de type library possible, etc.). Le composant DCOM est censé ne pas supporter l'interface IDispatch.

    J'ai cherché plusieurs pistes dont utilisation du TDCOMConnection (semble lié à l'interface MIDAS uniquement), ... mais sans succés!

    Appel dynamique à une méthode DCOM = utilisation obligatoire d'OLE? ou existe-t-il une manière dynamique de récupérer l'interface et l'appeler sans type library?

    Merci!

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Bonjour et bienvenue sur les forums de Développez.com

    Mmmh je ne suis pas sûr de tout bien comprendre ce que vous voulez faire, mais je pense que vous devriez chercher du côté de CreateComObject et CreateRemoteComObject. Affectez l'interface retournée à une variable de type OleVariant et vous pouvez ensuite appelez les méthodes sans avoir besoin de la déclaration exacte de l'interface retournée.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2002
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Effectivement je souhaite utiliser CreateRemoteCOMObject avec du code similaire à celui ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      vMyCOMObj : Variant;
    begin
      vMyCOMObj:= CreateRemoteCOMObject('MonServeur', StringToGUID('{monGUID}');  
      monResultat := vMyCOMObj.MaFonctionAdd(1,2);
    mais sans appel direct à la fonction 'MaFonctionAdd' dans l'exemple ci dessus

    J'ai cherché une solution qui me permettrait de récupérer un pointeur de fonction vers MaFonctionAdd, puis un appel via le pointeur de fonction, mais sans déclaration du type de fonction,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     // Récupérer le pointeur de fonction d'une fonction remote, "à la manière de" GetProcAddress (qui ne fonctionne qu'avec un serveur in-proc, je crois?)
     maProcAddr := GetRemoteProcAddress(vMyCOMObj, 'MaFonctionAdd');
     // puis appel
     monResultat := maProcAddr(1,2);
    mais deux soucis dans le pseudo-code ci dessus:
    1) GetRemoteProcAddress n'existe pas, et pas trouvé comment le coder...
    2) sans déclaration du type de fonction, un appel à maProcAddr(1,2) provoque une erreur du compilateur

    ?

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Et tu as essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var
      vMyCOMObj : IDispatch;
    begin
      vMyCOMObj:= CreateRemoteCOMObject('MonServeur', StringToGUID('{monGUID}') as IDispatch;
    Puis de faire les appels à vMyCOMObj en utilisant la méthode Invoke ?
    Je ne sais pas si ça marchera, mais sans TLB c'est la seule chose qui a une chance de fonctionner.
    A moins que tu ne veuilles encoder les appels RPC à la main, et donc faire du RPC côté client, en récupérant du DCOM côté serveur. Ca doit être théoriquement possible (ça revient à écrire ta propre classe pour le marshalling côté client), mais c'est très complexe.

    Sinon, sur le principe pour faire du DCOM tu as besoin de la TLB côté serveur et côté client, de façon à ce que Windows sache comment créer les proxys qui vont dialoguer entre eux.
    Par contre, il n'est pas indispensable de connaître cette TLB au moment de la compilation.

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2002
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Oui, les appels via l'interface IDispatch/Invoke fonctionnent bien
    Mais il me semble que IDispatch doit être implémenté uniquement pour les serveurs OLE et ActiveX, mais n'est pas requise pour les serveurs COM/DCOM (seul IUnknown serait requis pour ces serveurs?).

    Je suppose que Delphi réalise ce type d'appel en interne lorsqu'on écrit:
    vMonObjet := CreateRemoteCOMObject('serveur','GUID');
    // vMonObjet n'est pas un objet OLE, ne supporte pas IDispatch
    vMonObjet.MaFonction(1,2);

    Auriez vous une idée de la méthode utilisée par le compilateur afin de résoudre cet appel? (Comment récupérer le pointeur sur MaFonction, et comment déclencher/forcer un appel avec paramètres sans erreur du compilateur)

  6. #6
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    IDispatch doit être implémenté chaque fois que l'on veut pouvoir travailler en late-binding.
    C'est donc une nécessité si l'objet doit être appelé depuis un langage de script, donc une nécessité pour un ActiveX ou pour de l'OLE Automation.

    Dans tous les autres cas effectivement, seul IUnknown est indispensable.

    Je suppose que Delphi réalise ce type d'appel en interne lorsqu'on écrit:
    vMonObjet := CreateRemoteCOMObject('serveur','GUID');
    // vMonObjet n'est pas un objet OLE, ne supporte pas IDispatch
    vMonObjet.MaFonction(1,2);
    Effectivement, dans ce cas "MaFonction(1, 2)" est encodée sous la forme d'appels à IDispatch. C'est le rôle de cette interface.

    Auriez vous une idée de la méthode utilisée par le compilateur afin de résoudre cet appel? (Comment récupérer le pointeur sur MaFonction, et comment déclencher/forcer un appel avec paramètres sans erreur du compilateur)
    Il appel IDispatch et Invoke et laisse l'objet derrière se débrouiller pour comprendre ce que l'on essaie de faire.

    Quoi qu'il en soit, tu ne peux pas faire de DCOM sur un objet distant si tu ne possèdes pas sa TLB ! DCOM fonctionne de cette façon :
    Lorsque tu instancies ton objet DCOM, Windows te renvoie un objet Proxy qui implémente la même interface que celle que tu veux utiliser sur l'objet DCOM.
    Lorsque tu fais un appel de méthode en DCOM, tu fais en réalité un appel COM classique à l'objet Proxy. Ce dernier comprend alors que tu essaie d'appeler la méthode xxxx de l'objet distant et encode un appel RPC sur ce dernier.

    Pour que celà fonctionne, il faut que Windows (et j'ai bien dit Windows, tu n'as pas la main la dessus) connaisse exactement l'interface que tu veux appeler pour qu'il puisse créer un objet Proxy adapté.

    Sans TLB, Windows ne peut pas créer l'objet Proxy. Donc tu ne peux pas récupérer l'interface à appeler...

    Si tu utilises IDispatch, Windows connait cette interface puisqu'elle fait partie du coeur même de COM. Donc Windows peut créer l'objet Proxy et envoyer les appels Invoke à l'objet distant.

    Donc en résumé, si tu n'as pas la TLB et que l'objet distant n'implémente pas IDispatch, ta seule chance de l'appeler serait de faire toi même les appels RPC que ferait DCOM si tu connaissais l'interface.
    Ca doit être théoriquement possible, mais tu ferais mieux d'envisager une autre solution...

    Par exemple, tu pourrais peut-être utiliser un objet DCOM intermédiaire sur la machine distante : Tu ferais tes appels DCOM via un IDispatch sur cet objet. Puis ce dernier se chargerait d'instancier l'objet COM correspondant et ensuite d'effectuer l'appel à l'interface en VTable.

  7. #7
    Membre à l'essai
    Inscrit en
    Mai 2002
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 22
    Points : 12
    Points
    12
    Par défaut
    Merci Franck, explications trés claires
    Je ne souhaite pas me lancer dans l'écriture de proxy/stub et retiens donc l'idée de la passerelle (Remote)OLE->COM
    A+

Discussions similaires

  1. [CR8.5] Image dynamique sans utiliser RDC ou Blob
    Par lrp dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 21/12/2005, 14h43
  2. Script Java appelé dans Xsl sans résultats
    Par metallic dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 03/08/2005, 15h39
  3. Comment appeller un ActiveX de type Exe en JAVASCRIPT ?
    Par mandarindi dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 23/03/2005, 09h57
  4. Appeler une API sans liaison avec une DLL
    Par mat.M dans le forum x86 32-bits / 64-bits
    Réponses: 10
    Dernier message: 13/07/2004, 02h22
  5. [LG]Problême Variable dynamique de types différents
    Par pierrOPSG dans le forum Langage
    Réponses: 2
    Dernier message: 29/04/2004, 16h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo