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

C++ Discussion :

Passage d'objets entre DLL


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Passage d'objets entre DLL
    Hello,

    J'ai cru comprendre que lorsqu'un programme principal souhaite communiquer avec une de ses DLL, quelques problèmes risquent de survenir avec les types non primitifs.

    Par exemple, si une fonction dans une DLL appelle une fonction dans le programme princiapal en lui passant un objet, ça pouvait planter à cause du mangling. La solution étant paraît-il de s'assurer que la compilation se passe exactement dans les mêmes conditions (paramètres, etc.).

    Mais pourtant, il est possible d'utiliser des API en release qui renvoient sans problème des objets alors qu'on développe en Debug.

    Par ailleurs, si on envoie un pointeur vers un objet créé dans la DLL, le programme principal interprétera-t-il correctement l'objet lorsque le pointeur sera transtypé ?

    Toute info sur le suejt serait la bienvenue, car je suis complètement paumé (déjà que je ne suis pas très à l'aise avec les DLL...).

    Merci.

  2. #2
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Salut,

    Pour avoir déjà un peu travaillé sur un programme qui fonctionnait comme ça, tu peux passer un pointeur et le re-caster derrière, mais il faut bien sûr que ce soit le même type de la même taille.
    En gros, tu passes une structure de la composition que tu veux avec les infos du genre:
    • ID de la structure
    • le pointeur de l'objet
    • le type de l'objet
    • sa taille
    L'ID est pour différentier les messages systèmes qui arrivent dans le programme des tiens. Il faut donc que tu surcharges la pompe à messages de la DLL qui reçoit pour dispatcher au bon endroit les messages qui t'intéressent, et faire ensuite le cast adéquat.

    Bon courage

  3. #3
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par oodini Voir le message
    J'ai cru comprendre que lorsqu'un programme principal souhaite communiquer avec une de ses DLL, quelques problèmes risquent de survenir avec les types non primitifs.
    Non absoluement aucun, si on sait ce qu'on fait.
    Par exemple, si une fonction dans une DLL appelle une fonction dans le programme principal en lui passant un objet, ça pouvait planter à cause du mangling. La solution étant paraît-il de s'assurer que la compilation se passe exactement dans les mêmes conditions (paramètres, etc.).
    Je ne sais pas de quel mangling tu parles, mais quelque soit la DLL, même avec des types 'simples', il faut que les conventions d'appel des fonctions soient parfaitement définies.. C'est pour cette raison, que toutes les déclarations de fonctions en "DLL" sont en général préfixées par leur convention (même si c'est inutile), histoire que le compilo, même règlé sur une autre convention utilise la bonne a l'appel de la fonction.
    Mais pourtant, il est possible d'utiliser des API en release qui renvoient sans problème des objets alors qu'on développe en Debug.
    Hmmm... renvoyer un objet ? ca dépend des APIs... Certaines APIs n'ont pas la même signature d'objet (taille par exemple) entre la version debug et la version release, avec au bout du compte des crashs intempestifs lors des copies d'objets....
    Par ailleurs, si on envoie un pointeur vers un objet créé dans la DLL, le programme principal interprétera-t-il correctement l'objet lorsque le pointeur sera transtypé ?
    Là c'est différent ! Un pointeur est un type simple... Par contre, le transtypage indique que tu comptes l'utiliser non comme un simple pointeur mais comme un objet... Il faut donc que les deux objets aient une définition absoluement identique.

    C'est pour cette raison, que, quand on utilise des DLLs en C++, on passe en général par un système d'interfaces ... Une interface est une structure ne comportant que des méthodes virtuelles. Et cette interface peut facilement être implémentée par les objets de la DLL et utilisée par le programme principal (ou réciproquement d'ailleurs).
    Si en plus on veut gérer une durée de vie "smart", alors, le principe "celui qui alloue est celui qui désalloue" implique un compteur intrusif (systeme AddRef/Release).
    Si au final on veut pouvoir gérer plusieurs versions des interfaces (DLL et EXE évoluant a des rythmes différents), alors il faut un système de transtypage d'interfaces (aka QueryInterface). Et on se retrouve avec la base de COM.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par nicroman Voir le message
    Je ne sais pas de quel mangling tu parles, mais quelque soit la DLL, même avec des types 'simples', il faut que les conventions d'appel des fonctions soient parfaitement définies.. C'est pour cette raison, que toutes les déclarations de fonctions en "DLL" sont en général préfixées par leur convention (même si c'est inutile), histoire que le compilo, même règlé sur une autre convention utilise la bonne a l'appel de la fonction.
    Je me réfère à ce qui m'avait été dit dans ce fil.

    Citation Envoyé par nicroman
    Hmmm... renvoyer un objet ? ca dépend des APIs... Certaines APIs n'ont pas la même signature d'objet (taille par exemple) entre la version debug et la version release, avec au bout du compte des crashs intempestifs lors des copies d'objets....
    Ben par exemple, sur cette page, tu peux voir que pas mal de fonctions renvoient des MString.

    Citation Envoyé par nicroman
    Là c'est différent ! Un pointeur est un type simple... Par contre, le transtypage indique que tu comptes l'utiliser non comme un simple pointeur mais comme un objet... Il faut donc que les deux objets aient une définition absoluement identique.
    Ben à moins de faire l'arithmétique de pointeurs, ces derniers s'utilisent en général comme des objets (via l'opérateur ->), non ?

    Citation Envoyé par nicroman
    C'est pour cette raison, que, quand on utilise des DLLs en C++, on passe en général par un système d'interfaces ... Une interface est une structure ne comportant que des méthodes virtuelles. Et cette interface peut facilement être implémentée par les objets de la DLL et utilisée par le programme principal (ou réciproquement d'ailleurs).
    Si en plus on veut gérer une durée de vie "smart", alors, le principe "celui qui alloue est celui qui désalloue" implique un compteur intrusif (systeme AddRef/Release).
    Si au final on veut pouvoir gérer plusieurs versions des interfaces (DLL et EXE évoluant a des rythmes différents), alors il faut un système de transtypage d'interfaces (aka QueryInterface). Et on se retrouve avec la base de COM.
    Tout cela n'a pas l'air simple, et je n'ai pas l'impression que ça pourra se régler sur un forum. Tu sais où je pourrais trouver de la doc, là-dessus ?

    Merci, en tout cas !

  5. #5
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par oodini Voir le message
    Je me réfère à ce qui m'avait été dit dans ce fil.
    Oui, c'est à dire exactement la même chose...
    Renvoyer/utiliser un objet c'est bien, à condition d'être sur que cet objet a *exactement* la même signature entre l'utilisateur et le serveur (la DLL). Sinon... c'est le drame !
    L'exemple type est effectivement std::string qui a été modifié avec un Service Pack !!
    Si ton but est d'avoir juste une application structurée en modules, tu peux faire comme tu le sens... si ton but est d'avoir un vrai système de DLL (mettre à jour une partie du code sans toucher le reste), alors c'est la meilleure façon de se planter (la quantité de QA nécessaire est relative au carré du nombre de versions sorties).

    Maintenant screetch te conseille d'utiliser exactement les mêmes options de compilation principalement pour des raisons de signatures (les objets debug sont souvent différement des objets release).

    Mais c'est vraiment très facile de rajouter un truc genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class MADLL_API MaClassExportee
    {
         public:
              void   FASTCALL   AddRef();
              void   FASTCALL   Release();
    };
    Ensuite, que le compilo soit réglé en FASTCALL ou CDECL, ou STDC, l'appel de ces deux fonctions se fera toujours en FASTCALL !


    Ben par exemple, sur cette page, tu peux voir que pas mal de fonctions renvoient des MString.
    Ben ils font ce qu'ils veulent... je leur souhaite bien du courage pour modifier la signature de la classe MString (adieu compatibilité).

    Ben à moins de faire l'arithmétique de pointeurs, ces derniers s'utilisent en général comme des objets (via l'opérateur ->), non ?
    Oui, c'est pour ca qu'on passe par des pointeurs d'interface...

    Tout cela n'a pas l'air simple, et je n'ai pas l'impression que ça pourra se régler sur un forum. Tu sais où je pourrais trouver de la doc, là-dessus ?

    Merci, en tout cas !
    Regardes un peu la doc de COM (juste les bases) par exemple...
    Et sinon, le 'pur' orienté objet (un objet n'est jamais vu de l'exterieur que par une, ou plusieurs, interface(s)... ceci dit, c'est un peu la philosophie de COM).

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    Attention, FASTCALL diffère entre les compilateurs. Donc, à déconseiller pour les fonctions publiques d'une DLL.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/03/2007, 15h28
  2. Probleme de passage de string entre DLL win32 et projetC#?
    Par Jayceblaster dans le forum C++/CLI
    Réponses: 15
    Dernier message: 17/11/2006, 13h10
  3. [C#] passage d'objet entre forms
    Par kooljy dans le forum Windows Forms
    Réponses: 4
    Dernier message: 26/04/2006, 06h45
  4. [langage] Passage d objet entre deux fichiers
    Par Slippers dans le forum Langage
    Réponses: 2
    Dernier message: 28/04/2005, 14h45
  5. Réponses: 4
    Dernier message: 02/01/2005, 23h24

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