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

Qt Discussion :

Compiler une DLL sous Qt


Sujet :

Qt

  1. #1
    Membre éclairé
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Points : 812
    Points
    812
    Par défaut Compiler une DLL sous Qt
    Bonjour,
    Voilà plusieurs questions concernant les dll.

    Tout d'abord, pourquoi une dll doit elle forcement etre compilée en C pour qu'elle fonctionne sous Qt quand on la charge avec QLibrairy?

    Ensuite, j'aimerai savoir s'il est possible de créer des dll avec Qt, où on dedans, il y aurai une fonction qui ouvrirai une nouvelle fenetre ( héritant de QWidget ), depuis un autre programme.
    Un peu comme un système de plugin...
    Est ce possible?

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Hello,

    Citation Envoyé par ZouBi Voir le message
    Tout d'abord, pourquoi une dll doit elle forcement etre compilée en C pour qu'elle fonctionne sous Qt quand on la charge avec QLibrairy?
    Il ny a pas de contrainte de ce genre. Tu veux peut etre parler de la difficulte de recuperer dynamiquement le nom des fonctions de la dll. Le C est un langage assez "pauvre" alors le nom des fonctions exportees peut etre le meme que la fonction dans le code. En C++, il y a d'autres aspects qui font qu'une meme fonction peut exister en plusieurs "versions" : dans des namespaces/classes/struct differentes, avec un nombre de parametres differents, etc... Du coup y'a un procede de "decoration de noms" = name mangling qui encode de maniere unique le nom de ta fonction.
    Pour comprendre un peu mieux tout cela, ouvre une dll Qt (QtCore.dll) avec dependency walker:
    http://www.dependencywalker.com/
    et joue avec le bouton de demangling C++.

    Ensuite, j'aimerai savoir s'il est possible de créer des dll avec Qt,
    Qt est une bibliotheque C++, le fait de creer une dll est de la responsabilite du compilo, pas des bibliotheques. Donc Qt ne joue pas vraiment, du moins directement. Cela dit qmake te propose une template pour creer simplement un projet DLL avec le compilo de ton choix.

    où on dedans, il y aurai une fonction qui ouvrirai une nouvelle fenetre ( héritant de QWidget ), depuis un autre programme.
    Un peu comme un système de plugin...
    Ta DLL peut en interne utiliser a peu pres tout ce qu'elle veut. Les problemes surviennent si tu souhaites faire "sortir" de ta dlls des objets qu'elle a cree. c.a.d que si tu veux creer une fonction qui renvoie un QWidget, il faut faire attention a certaines choses, surtout de maniere dynamique (plugin).

    Maintenant si ta fonction ouvre une fenetre et la ferme avant de rendre la main, y'a pas trop de restrictions. Pour info Qt utilise des plugins C++ en divers endroits. Pour les base de donnees, pour QtDesigner, etc...

  3. #3
    Membre éclairé
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Points : 812
    Points
    812
    Par défaut
    ok merci,
    Tout ce que j'veux c'est qu'elle ouvre une fenetre, tout simplement.
    Donc pour creer une dll avec Qt, faut quand même que j'passe par la librairie window.h; et utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define DLL_EXPORT __declspec(dllexport)
    #define DLL_IMPORT __declspec(dllimport)
    tout simplement?

    Oui, et aussi concernant le C++, exactement, en compilant, dans la DLL, le nom d'une fonction genre "plugin" n'est plus d'origine, mais du genre "_Z6pluginv @1"

    donc ca fait que dans mon programma principale, qui n'appelle seulement la fonction "plugin" contenue dans une DLL, bah ça ne fonctionne pas.

    J'ai testé ton programme en ouvrant ma DLL, et utiliser le bouton "Undecorate C++ Functions", ca ne fait rien.

    Comment régler ce problème de nom?

    J'ai essayé avec un fichier.def

    test.dll
    libtest.def
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    EXPORTS
    plugin _Z6pluginv @1
    Je met ces deux fichiers dans le dossier de mon application, mais celle ci ne trouve toujours pas la fonction "plugin" dans la dll.

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par ZouBi Voir le message
    ok merci,
    Tout ce que j'veux c'est qu'elle ouvre une fenetre, tout simplement.
    La question c'est pas d'ouvrir, c'est de fermer... Qui ferme la fenetre, et quand? Par exemple, si ton appli fait ca:
    - charge le plugin
    - appelle ta fonction -> creation de la fenetre, sans la fermer (aie aie, debut des problemes)
    - decharge plugin

    Ke bayo?

    Un autre aspect important est est-ce que le programme qui appelle est aussi un programme GUI? Quelle lib GUI?

    Donc pour creer une dll avec Qt, faut quand même que j'passe par la librairie window.h; et utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define DLL_EXPORT __declspec(dllexport)
    #define DLL_IMPORT __declspec(dllimport)
    tout simplement?
    non

    Encore une fois, ce n'est pas un probleme de lib. Ni Qt, ni "windows.h" (API Win32). Ton code ne fait qu'un #define de mot cle specifique a ton compilateur (extension au C++ standard).

    Et ca ne marche pas comment tu l'as ecris, parce que la distinction export/import est juste une histoire de contexte. Si tu compiles la dll, c'est un export. Si tu lies statiquement (code client), c'est un import. C'est donc plutot dans ce genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef COMPILE_LA _DLL
    #define DLL_EXPORT_OR_IMPORT __declspec(dllexport)
    #else
    #define DLL_EXPORT_OR_IMPORT __declspec(dllimport)
    #endif
    En general, on utilise juste le nom DLL_EXPORT, meme pour l'import.

    Oui, et aussi concernant le C++, exactement, en compilant, dans la DLL, le nom d'une fonction genre "plugin" n'est plus d'origine, mais du genre "_Z6pluginv @1"
    Yes, cest le namemangling en action, qui est specifique a chaque compilo.

    donc ca fait que dans mon programma principale, qui n'appelle seulement la fonction "plugin" contenue dans une DLL, bah ça ne fonctionne pas.

    J'ai testé ton programme en ouvrant ma DLL, et utiliser le bouton "Undecorate C++ Functions", ca ne fait rien.
    Le name mangling etant specifique a chaque compilo, le demangling lui est aussi specifique. dependency walker ne fonctionne qu'avec VC++. Si tu as compile avec g++, ben c'est normal qu'il n'y arrive pas.

    Comment régler ce problème de nom?
    Il faut demander au compilo de ne pas mangler ta fonction a la C++. Mais pour cela, il faut respecter certaines contraintes, qui sont celles des fonctions C. A savoir convention d'appel stdcall (extern "C") suffit en general.

    J'ai essayé avec un fichier.def

    Je met ces deux fichiers dans le dossier de mon application, mais celle ci ne trouve toujours pas la fonction "plugin" dans la dll.
    Ben oui, elle n'existe pas. Seule la fonction _Z6pluginv existe, d'un point de vue du linker.

  5. #5
    Membre éclairé
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Points : 812
    Points
    812
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    La question c'est pas d'ouvrir, c'est de fermer... Qui ferme la fenetre, et quand? Par exemple, si ton appli fait ca:
    - charge le plugin
    - appelle ta fonction -> creation de la fenetre, sans la fermer (aie aie, debut des problemes)
    - decharge plugin

    Ke bayo?
    Ca c'est pas un soucis, je m'en chargerai.

    [QUOTE=Aurelien.Regat-Barrel;3274491]
    Un autre aspect important est est-ce que le programme qui appelle est aussi un programme GUI? Quelle lib GUI?
    [QUOTE]
    Le programme appelant, et la DLL seront des programmes GUI avec Qt.

    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    non
    Encore une fois, ce n'est pas un probleme de lib. Ni Qt, ni "windows.h" (API Win32). Ton code ne fait qu'un #define de mot cle specifique a ton compilateur (extension au C++ standard).
    Non, désolé, je me suis mal exprimé, tout ce que je voulais dire par là, c'est que ca fonctionne pareil,
    je déclare la macro
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define DLL_EXPORT __declspec(dllexport)
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    Yes, cest le namemangling en action, qui est specifique a chaque compilo.
    Le name mangling etant specifique a chaque compilo, le demangling lui est aussi specifique. dependency walker ne fonctionne qu'avec VC++. Si tu as compile avec g++, ben c'est normal qu'il n'y arrive pas.
    Il faut demander au compilo de ne pas mangler ta fonction a la C++. Mais pour cela, il faut respecter certaines contraintes, qui sont celles des fonctions C. A savoir convention d'appel stdcall (extern "C") suffit en general.
    J'ai essayé avec un fichier.def
    Ben oui, elle n'existe pas. Seule la fonction _Z6pluginv existe, d'un point de vue du linker.
    On en revient donc à mon soucis, comment puis je faire?

  6. #6
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 749
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 749
    Points : 10 666
    Points
    10 666
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par ZouBi Voir le message
    Le programme appelant, et la DLL seront des programmes GUI avec Qt
    Ah, voila qui simplifie

    Si ton programme et ta dll sont compiles avec le meme compilateur (tout pareil), la meme version de Qt, alors ca peut te simplifier pas mal de choses. Tu peux renvoyer un QWidget a l'appli mere depuis le plugin, etc... sans probleme, a condition que:
    - Qt soit utilise sous forme de dll
    - que tout le monde utilise le runtime C++ sous forme de dll (ce qui est le cas par defaut avec VC++) => pas de Qt sous forme de lib statique!

    Citation Envoyé par ZouBi
    On en revient donc à mon soucis, comment puis je faire?
    Declare ta fonction C++ comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    __declspec(dllexport) extern "C" void* fonction()
    {
    }
    Mais prends un peu de temps pour jeter un oeil aux plugins de Qt:
    http://qt.developpez.com/doc/latest/...t-applications

  7. #7
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    Mais prends un peu de temps pour jeter un oeil aux plugins de Qt:
    http://qt.developpez.com/doc/latest/...t-applications
    Gros +1 là-dessus
    Tu définis une interface abstraite décrivant les contrats à remplir par chaque extension, et zou, tu en implémentes une par projet dll et c'est bon. Faut pas oublier de bien tout recompiler à chaque fois que la classe abstraite change (ou plus exactement que la version de cette classe change, tu comprendras en lisant la doc).

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/01/2010, 12h23
  2. Utilisation d'une Dll sous Visual C++
    Par Hokagge dans le forum MFC
    Réponses: 3
    Dernier message: 11/01/2006, 14h40
  3. [VB] COmment compiler une dll dans un exe (zlib.dll)
    Par Khrysby dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 01/11/2005, 12h10
  4. Réponses: 5
    Dernier message: 08/09/2005, 20h33
  5. Enrgistrer une dll sous IIS
    Par jeff37 dans le forum ASP
    Réponses: 2
    Dernier message: 12/07/2004, 17h23

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