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 :

Librairie static incluse dans librairie dynamique


Sujet :

C++

  1. #1
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut Librairie static incluse dans librairie dynamique
    Bonjour,

    J'ai cr�er une librairie qui utilise les librairie tinyxml et libjpeg.
    Ayant seulement envie d'int�grer et de distribu� ma librairie j'ai decid� de faire la chose suivant:

    Je compile tinyxml en static
    Je compile libjpeg en static

    Puis je compile malib en dynamic en incluant les versions deux autres librairies:

    Sous MinGW les commandes pour linker donnent:

    C:\MinGW\bin\ar.exe cr ..\lib\libtinyxml.a tinystr.cpp.obj tinyxml.cpp.obj \tinyxmlerror.cpp.obj tinyxmlparser.cpp.obj
    C:\MinGW\bin\ranlib.exe ..\lib\libtinyxml.a

    meme chose pour jpeg

    C:\MinGW\bin\gcc.exe -shared -o bin\malib.dll -Wl,--out-implib,lib\malib.dll.a -Wl,--major-image-version,1,--minor-image-version,0 obj1.o obj2.o obj3.o 3rdparty\lib\liblibjpeg.a 3rdparty\lib\libtinyxml.a

    Au final quand je cr�er mon programme je doit utiliser:

    C:\MinGW\bin\g++.exe -Wall main.cpp.obj -o bin\AdVisOr.exe -Wl,--out-implib,lib\libAdVisOr.dll.a -Wl,--major-image-version,0,--minor-image-version,0 lib\malib.dll.a 3rdparty\lib\liblibjpeg.a 3rdparty\lib\libtinyxml.a

    alors que j'aimerais ne pas avoir a inclure 3rdparty\lib\liblibjpeg.a 3rdparty\lib\libtinyxml.a, car du coup cela me d�savantage de devoir inclure de nouveaux les librairies static.

    Je ne trouve pas grand chose sur le Web et j'utilise Cmake pour la compilation.

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Tout simplement parce que tu as export� des �l�ments de tes deux librairies statiques dans l'interface de ta librairie dynamique... Du coup, un programme utilisant la DLL doit linker aussi avec les librairies statiques pour r�ussir � trouver tous les symboles.

    Typiquement, c'est mettre dans un ent�te de classe un attribut qui est d�fini dans une librairie statique (=> demande � faire une classe interm�diaire et/ou du cast sauvage avec void*) et/ou du code (toujours dans le .H) utilisant directement les fonctions de la librairie statique (=> les mettre dans le .CPP).

    Tu as aussi la farce quand ton compilateur exporte par d�faut TOUTES les fonctions de la DLL, au lieu de se limiter � celles d�finies explicitement. L�, faut voir la doc du compilo pour savoir comment emp�cher l'exportation d'un symbole dans une DLL.

    Il te faut :
    • V�rifier ce que ta DLL exporte actuellement (via Dependancy Walker), afin de rep�rer l'�l�ment posant probl�me.
    • Repenser ton interface DLL de fa�on � n'exposer QUE tes propres fonctions / classes, en MASQUANT l'impl�mentation / utilisation des �l�ments des deux librairies statiques.
      Ceci implique un remaniement lourd de tes ent�tes, l'utilisation de classes plus g�n�riques qui seront les seules r�ellement export�es, l'utilisation de "void*" � outrance avec casts internes pour masquer le type r�el de l'impl�mentation, ...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut
    Oky, merci

    donc si j'utilise des fonctions de tinyxml dans ma libraires et dans mon programmes j'ai int�r�t a l'utiliser en tant que shared, ou directement inclure le code dans malib.dll.

    Par contre si j'arrive a cacher libjpeg c'est mieux de le compiler en statique et de le cacher dans malib.

    c'est bien ca ?

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Je vais prendre un exemple, ce sera plus clair...

    Voici par exemple un bout du code d'une librairie statique :
    Code Private.h : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <........>
     
    // Structure de contrôle utilisée partout dans la librairie pour toutes les fonctions, comme l'est "FILE*" pour l'accès aux fichiers.
    typedef struct {
     ....
     ....
     ....
    } private_handle ;
    Ce code est cens�, � priori, rester "planqu�" et non visible depuis ta DLL.

    Or, imaginons que tu as un ent�te public de ta DLL construit ainsi :
    Code Public.h : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include "Private.h" // pour "private_handle"
    
    class Bidule {
    
      // Ouverture d'une ressource. La valeur de retour est pass� � toutes les m�thodes de la classe, MAIS L'UTILISATEUR NE LA MANIPULE JAMAIS DIRECTEMENT.
      // La m�thode met � jour l'attribut m_PrivateHandle de la classe.
      bool Open ( .... ) ;
    
      // Travail effectif.
      int Process ( ..... ) ;
    
      // Fermeture.
      bool Close ( void ) ;
    
    private:
      private_handle* m_PrivateHandle ;
    
    } ;

    Probl�me : private_handle fait partie de la librairie statique, devrait �tre priv�, et est utilis� par une classe publique via un attribut... Du coup, pour pouvoir compiler, tu dois inclure l'ent�te de la librairie statique, qui va bien entendu forcer un link de cette librairie statique au sein de ton ex�cutable, alors que tu croyais n'utiliser que ta DLL !!

    Pour corriger, tu devras faire ainsi :
    Code Public.h : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // On supprime le #include public vers la librairie statique.
    
    class Bidule {
    
      // Ouverture d'une ressource. La valeur de retour est pass� � toutes les m�thodes de la classe, MAIS L'UTILISATEUR NE LA MANIPULE JAMAIS DIRECTEMENT.
      // La m�thode met � jour l'attribut m_PrivateHandle de la classe.
      bool Open ( .... ) ;
    
      // Travail effectif.
      int Process ( ..... ) ;
    
      // Fermeture.
      bool Close ( void ) ;
    
    private:
      void* m_MaskedPrivateHandle ;  // Passage en void*
    
    } ;
    Code Public.cpp : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include "Public.h"
    #include "Private.h" // pour "private_handle", il passe donc dans le CPP.
     
    bool Bidule::Open ( .... ) {
     
      private_handle* m_PrivateHandle ;
     
      // Reste de la fonction.
     
      // Affectation de l'attribut avec cast.
      m_MaskedPrivateHandle = static_cast<void*>(m_PrivateHandle) ;
    }
     
    int Bidule::Process ( ..... ) {
     
      // Via un cast, on récupère le handle "normalement", avec l'ancien nom d'attribut pour éviter d'avoir à modifier inutilement le code déjà écrit.
      private_handle* m_PrivateHandle = static_cast<private_handle*>(m_MaskedPrivateHandle) ;
     
      // Corps de la fonction, inchangé désormais.
    }
     
    ...
    Ainsi, m�me si la DLL continue d'utiliser la librairie statique, cela n'est pas visible de l'ext�rieur, et aucun ent�te de la librairie statique n'est requis. Du coup, ton ex�cutable n'aura plus besoin d'�tre link� avec la librairie statique en question...


    Tu vois mieux de quoi je veux parler ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut
    Oky, parfait ...
    merci pour l'aide

  6. #6
    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
    Je pense que Mac y va un peu fort....

    Si ton entete est:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    struct mallibprivatestruct;
    class DLL_EXPORT DeMaLib
    {
        private:
          malibprivatestruct*   m_pStruct;
    };
    Personne (utilisateur) n'a besoin d'avoir la d�finition de malibprivatestruct, juste celle d'un pointeur !

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Citation Envoy� par nicroman Voir le message
    Personne (utilisateur) n'a besoin d'avoir la d�finition de malibprivatestruct, juste celle d'un pointeur !
    Et en utilisant ta DLL via cette interface, ton ex�cutable va gueuler comme quoi tu as une d�claration forward non r�solue...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  8. #8
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut
    Ouais exactement, je faisait �a avant et avait des probl�mes avec ce genre de manip!

    il me reste encore un petit probl�me avec le compilateur MVC et ce bout de code.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    class X7sParamList {
    private:
    std::map<int,X7sParam*> m_mapID;
    }
    Et la le void* ne me fonctionne pas

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Citation Envoy� par elraton Voir le message
    Et la le void* ne me fonctionne pas
    Ben si, mais c'est dans tout ce qui va utiliser ton X7sParamList qu'il faudra faire les casts. Mais tu peux sans probl�me modifier ton X7sParam* en void*, toutefois l'appel / utilisation de X7sParamList risque d'�tre un peu lourdingue.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  10. #10
    Membre confirm�
    Inscrit en
    Juin 2003
    Messages
    223
    D�tails du profil
    Informations personnelles :
    �ge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par d�faut
    nan en fait c'est le std::map<> qui me donne des erreurs car il s'agit d'un templates, et les templates dans les libraries ca donne tout plein de warning

  11. #11
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par d�faut
    Citation Envoy� par Mac LAK Voir le message
    Et en utilisant ta DLL via cette interface, ton ex�cutable va gueuler comme quoi tu as une d�claration forward non r�solue...
    J'ai du mal � comprendre �a... Pourrais-je avoir un exemple?
    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.

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Citation Envoy� par M�dinoc Voir le message
    J'ai du mal � comprendre �a... Pourrais-je avoir un exemple?
    Sous Visual, c'est une erreur C2079 ("'variable' utilise une struct de 'machin' non d�fini") qui peut �tre lev�e. Le code montr� par nicroman fonctionnera souvent, principalement dans les cas simples, mais aura de gros soucis dans certains cas d'utilisation plus complexes o� le type "malibprivatestruct*" sera d�r�f�renc� et/ou index� (ex : utilisation d'un "malibprivatestruct[20]" � la place d'un "malibprivatestruct*"), ce qui est toujours possible si l'attribut est public (ou m�me en protected, via h�ritage).

    Le probl�me �tant que l'erreur est alors plut�t cryptique, voire difficile � trouver, tandis qu'un masquage int�gral par "void*" n'occasionne jamais ce genre de soucis (on a alors, toujours sous VC++, une erreur C2182 ("utilisation non conforme du type 'void'"), ce qui est nettement plus clair �tant donn� que le type est clairement marqu� comme "void*").

    La mani�re "bourrine" de lever cette erreur est d'inclure les ent�tes de la librairie statique que l'on voulait justement masquer, et de linker avec : la C2079 est alors lev�e, mais on garde la d�pendance avec la librairie statique que l'on voulait justement ne plus avoir au niveau de l'ex�cutable. L'utilisation d'un void* explicite, par contre, masque int�gralement la librairie statique dans l'interface publique de la DLL, quoi qu'il arrive.

    Cela permet aussi, si besoin, de faire un masquage en C (non C++, donc) m�me sur des compilateurs anciens et/ou exotiques.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  13. #13
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par d�faut
    D'un autre c�t�, pour moi, tenter de d�r�f�rencer un malibprivatestruct*, c'est comme vouloir d�r�f�rencer un FILE* :
    "Y'en a qu'ont essay�, ils ont eu des probl�mes. Et c'est leur faute."
    J'aime que mes pointeurs opaques soient typ�s, �a �vite de les confondre.
    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.

  14. #14
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    D�tails du profil
    Informations personnelles :
    �ge : 51
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par d�faut
    Citation Envoy� par M�dinoc Voir le message
    D'un autre c�t�, pour moi, tenter de d�r�f�rencer un malibprivatestruct*, c'est comme vouloir d�r�f�rencer un FILE*
    Le but �tant d'avoir une DLL masquant des librairies statiques en les encapsulant, on peut (presque) l�gitimement penser que l'utilisateur final peut faire le neuneu en l'utilisant sans tomber sur des erreurs cryptiques... Sur un exemple tr�s simple, �a va, mais sur un "monstre" exportant des centaines de fonctions et types, �a peut vite devenir un enfer.

    Citation Envoy� par M�dinoc Voir le message
    J'aime que mes pointeurs opaques soient typ�s, �a �vite de les confondre.
    Personnellement, j'�vite plut�t d'exposer les donn�es priv�es, m�me dans une section "private:"... Je pr�f�re que l'utilisateur ne voie que ce qu'il a � utiliser, et rien d'autre, pas m�me un #define quelconque.

    En g�n�ral, j'utilise donc un .H "public" (export�, document� Doxygen et permettant d'avoir le manuel utilisateur), un .H "priv�" (exclus du manuel utilisateur, mais pr�sent en manuel du d�veloppeur) et un .CPP r�f�ren�ant les deux (inclus dans le manuel d�veloppeur bien s�r).

    Donc, en g�n�ral, je n'ai pas besoin d'avoir un void* visible depuis l'ext�rieur, mais cela demande � �tre pris en compte d�s la conception... Mais quand c'est pour r�soudre ce genre de probl�mes de link, il est plus rapide de passer en void* que de tout casser / refaire.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au s�rieux, de toutes fa�ons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum ad�quat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [Librairies] Inserer lignes dans fichier RTF
    Par tit_oune dans le forum Biblioth�ques et frameworks
    R�ponses: 5
    Dernier message: 04/05/2012, 10h21
  2. [WIN32][D2005] Integrer une librairie C/C++ dans Delphi
    Par ZeGothMan dans le forum Langage
    R�ponses: 8
    Dernier message: 30/03/2006, 13h56
  3. Inclusion de librairie sous visual
    Par petdelascar dans le forum C
    R�ponses: 11
    Dernier message: 07/12/2005, 20h39
  4. R�ponses: 5
    Dernier message: 25/04/2004, 00h57
  5. Inclusion de librairie rat�e
    Par glop - pas glop dans le forum MFC
    R�ponses: 21
    Dernier message: 15/02/2004, 18h41

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