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 :

Comment lier l'interface C d'une lib en C++?


Sujet :

C++

  1. #21
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Tu peux regarder ce fichier de configuration de la bibliothèque Ogre par exemple, et regarder comment ils déclarent la macro _OgreExport selon les différents systèmes :
    http://www.ogre3d.org/docs/api/html/...8h-source.html

  2. #22
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Tu peux regarder ce fichier de configuration de la bibliothèque Ogre par exemple, et regarder comment ils déclarent la macro _OgreExport selon les différents systèmes
    Ca va aider, mais on y voit que GCC (version antérieure à 4) n'accepte pas de syntaxe similaire à Windows. Donc je vois pas comment on y fait des librairies partagées. Mais l'important pour moi c'est Windows.

    J'ai créé ma petite DLL, mais j'ai déjà un 1er problème: j'arrive pas à la lier au programme.
    J'aimerais éviter l'édition de lien implicite (GetProcAdress) car j'ai vu dans la doc de Visual, qu'il y a la possibilité plus facile d'une édition de lien implicite.
    To implicitly link to a DLL, executables must obtain the following from the provider of the DLL:
    -A header file (.H file) containing the declarations of the exported functions and/or C++ classes.
    -An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.)
    -The actual DLL (.DLL file).
    Executables using the DLL must include the header file containing the exported functions (or C++ classes) in each source file that contains calls to the exported functions. From a coding perspective, the function calls to the exported functions are just like any other function call.

    To build the calling executable file, you must link with the import library. If you are using an external makefile, specify the file name of the import library where you list other object (.OBJ) files or libraries that you are linking with.
    C'est bien joli tout ça, mais je vois pas de fichier .LIB (import library) créé en même temps que la DLL, comme le suggère pourtant la doc de Visual.
    Des idées?

  3. #23
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    En fait, pour GCC, les fonctions sont exportées par défaut, il n'y a pas d'import/export à faire.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 400
    Par défaut
    1. GetProcAddress(), c'est EXplicite.
    2. Quelles sont tes options de compilation? regarde si tu n'as pas oublié d'en activer une... (genre "import library" à activer ou "doesn't produce .lib" à supprimer)


    Edit: Sous visual 2005 pro, j'ai l'option Project Properties->Configuration Properties->Linker->Advanced->Import Library
    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.

  5. #25
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Ca c'est de la réponse rapide. Merci

    Je comprends pas, ça marche maintenant, le linker me crée bien un '.dll' ET un '.lib'.
    J'avais juste vérifié dans le projet si l'option 'Import Library' était correcte, et elle l'était: "$(OutDir)/$(TargetName).lib". Je touche du bois...

  6. #26
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Ca marche nickel avec une DLL: plus de dépendance, et pas de changement majeur dans le code source grâce à l'édition de lien implicite.

    J'ai rajouté ceci dans l'entête de configuration

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #if defined(__ICL) || defined(_MSC_VER)
     
      //#define MALIB_API // pour compiler/utiliser la librairie statique
     
      #ifdef MALIB_EXPORT // à définir uniquement dans le projet/makefile
      #define MALIB_API __declspec(dllexport) // pour compiler en DLL
      #else
      #define MALIB_API __declspec(dllimport) // pour utiliser la DLL
      #endif
     
    #elif defined (__GNUC)
      #define MALIB_API
    #endif
    Je coupe les cheveux en 4, mais j'ai encore 2 petites questions:

    - Y a t-il un moyen de reconnaître automatiquement (avec un #ifdef ?) , si le projet compile une DLL ou une LIB? Ca m'éviterait d'avoir à modifier manuellement l'entête de configuration à chaque changement de projet.

    - Il faut que l'exécutable trouve la DLL. A ma connaissance, il faut donc que la DLL soit dans le même répertoire que l'executable ou bien dans l'un des répertoires du PATH. Mais ni l'un ni l'autre n'est pratique parce que la DLL est créée dans les répertoires MaLib/release ou MaLib/debug, et parce que j'ai plusieurs programmes qui utilisent la DLL. Y'a pas un moyen plus pratique pour que les executables trouve leur bonne (debug/release) DLL? et donc sans avoir à déplacer manuellement la DLL dans chaque répertoire des exécutables.

  7. #27
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    - Y a t-il un moyen de reconnaître automatiquement (avec un #ifdef ?) , si le projet compile une DLL ou une LIB? Ca m'éviterait d'avoir à modifier manuellement l'entête de configuration à chaque changement de projet.
    Non. Par contre il vaut mieux définir le symbole dans les options du préprocesseur plutôt que dans le code source.

    - Il faut que l'exécutable trouve la DLL. A ma connaissance, il faut donc que la DLL soit dans le même répertoire que l'executable ou bien dans l'un des répertoires du PATH. Mais ni l'un ni l'autre n'est pratique parce que la DLL est créée dans les répertoires MaLib/release ou MaLib/debug, et parce que j'ai plusieurs programmes qui utilisent la DLL. Y'a pas un moyen plus pratique pour que les executables trouve leur bonne (debug/release) DLL? et donc sans avoir à déplacer manuellement la DLL dans chaque répertoire des exécutables.
    Pas à ma connaissance. Par contre selon ton environnement, tu peux ajouter un PATH temporaire pendant l'exécution de tes projets qui requierent la DLL, ou encore faire un .bat qui copie la DLL où il faut, et exécuté automatiquement en étape de post-build.

  8. #28
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Je m'en doutais un petit peu...
    Encore merci

  9. #29
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    J'ai parlé trop vite, car finallement le problème reste entier.
    La DLL n'a certes pas de dépendances, mais la librarie d'importation en a.
    Je ne m'en suis pas rendu compte sur le coup car je travaille sous le même environnement (et les paths rendaient le problème transparent).

    A moins de se passer de la librairie d'importation, avec des appels explicites à la DLL, je vois pas comment faire. Mais la syntaxe des appels explicites (GetProcAdresse) me paraît tellement contraignante que je désire à tout prix l'éviter.

    Des idées?

  10. #30
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Normalement ça ne devrait pas être le cas. Les bibliothèques statiques devraient être compilées dans ta DLL et ne plus t'embêter. Peut-être une option de compilation à bidouiller ?

  11. #31
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Ca se complique.
    Je cerne un peu mieux le problème, mais c'est pas encore ça

    En fait j'utilise STLport pour compiler ma librairie, car d'après mes tests (qui datent certes un peu), celle-ci est plus rapide avec le compilo ICL que les STLs de VC ou de GCC pour les calculs mathématiques (en particulier sur les nombres complexes). Bref, j'utilise une librairie (statique ou dynamique, c'est selon) pour STLport.

    Je me mets dans la peau d'un utilisateur lambda, sans STLport mais utilisant la STL intégrée à Visual.Je réussis à lier mon programme avec ma DLL, mais son lancement m'annonce qu'il lui faut impérativement la DLL de STLport. Donc il y a dorénavant une dépendance dynamique (alors que la dépendance était auparavant statique avec les LIB)

    En plus, STLport à un comportement inhabituel pour lier la librairie (statique ou dynamique). Il n'est pas besoin de rajouter la dépendance dans l'édition de liens du projet comme d'hab.
    En fait il y a a qq part dans un '.h' de STLport une instruction pour importer la bonne librairie. (j'ai pas encore dénicher l'endroit dans le code. Vu que je connais pas l'instruction, c'est pas facile à trouver)
    Ca me laisse penser qu'il existe bien une possibilité, pour faire en sorte que le code C++ sache si le compilo est en mode statique ou dynamique)

    J'ai raison?
    Des pistes?

  12. #32
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Charlemagne
    Ca se complique.
    Je cerne un peu mieux le problème, mais c'est pas encore ça

    En fait j'utilise STLport pour compiler ma librairie, car d'après mes tests (qui datent certes un peu), celle-ci est plus rapide avec le compilo ICL que les STLs de VC ou de GCC pour les calculs mathématiques (en particulier sur les nombres complexes). Bref, j'utilise une librairie (statique ou dynamique, c'est selon) pour STLport.

    Je me mets dans la peau d'un utilisateur lambda, sans STLport mais utilisant la STL intégrée à Visual.
    Donc, au final, dans le programme, std::complex vaudra des choses différentes selon là où on se trouve ? C'est une violation de l'ODR, ce qui est un comportement indéfini. En pratique, pour ce genre de manip, il faut surtout éviter par dessus tout que des variables de tous ces types soient passé entre les deux bouts du programme.

    Citation Envoyé par Charlemagne
    Je réussis à lier mon programme avec ma DLL, mais son lancement m'annonce qu'il lui faut impérativement la DLL de STLport. Donc il y a dorénavant une dépendance dynamique (alors que la dépendance était auparavant statique avec les LIB)
    Oui, les DLL ne sont pas linkées... Puisque c'est tout leur intérêt...
    Pourquoi ne pas utiliser des libs statiques ? Il me semble que dans les options de projet d'une bibliothèque statique visual C++, tu as un onglet nommé Librerian qui te permet d'aggréger une autre bibliothèque statique avec la tienne. Il me semble que j'ai déjà eu des surprises avec cet onglet, mais je ne sais plus lesquelles, et c'était à un moment où j'avais pas eu le temps de prendre le temps de comprendre.

    Citation Envoyé par Charlemagne
    En fait il y a a qq part dans un '.h' de STLport une instruction pour importer la bonne librairie. (j'ai pas encore dénicher l'endroit dans le code. Vu que je connais pas l'instruction, c'est pas facile à trouver)
    Regarde un truc genre #pragma comment (lib:...)

    Citation Envoyé par Charlemagne
    Ca me laisse penser qu'il existe bien une possibilité, pour faire en sorte que le code C++ sache si le compilo est en mode statique ou dynamique)
    Souvent, le compilatuer définira des macros préprocesseur (genre DLL).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #33
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Il est tard, j'ai pas encore essayé tes propositions, mais ca devrait m'avancer sérieusement.

    Donc, au final, dans le programme, std::complex vaudra des choses différentes selon là où on se trouve ? C'est une violation de l'ODR, ce qui est un comportement indéfini. En pratique, pour ce genre de manip, il faut surtout éviter par dessus tout que des variables de tous ces types soient passé entre les deux bouts du programme.
    Je n'avais pas pensé à ce problème éventuel. Ca devrait pas être un problème pour les complexes dont le code est normalement intégralement dans les '.h', à moins d'instanciations explicites dans la librairie STL. Mais la remarque est pertinente. Y'a surement quelques fonctions instanciées (je pense aux entrées-sorties), mais pour l'instant j'ai pas vu de doubles définitions lors de l'édition de lien avec le programme utilisateur.
    Le problème sera peut-être plus flagrant avec ta proposition un peu plus loin d'aggréger des libs statiques.
    Que faire si y'a des doublets lors de l'édition de lien?

    Pourquoi ne pas utiliser des libs statiques ? Il me semble que dans les options de projet d'une bibliothèque statique visual C++, tu as un onglet nommé Librerian qui te permet d'aggréger une autre bibliothèque statique avec la tienne. Il me semble que j'ai déjà eu des surprises avec cet onglet, mais je ne sais plus lesquelles, et c'était à un moment où j'avais pas eu le temps de prendre le temps de comprendre.
    Ca aussi ça peut m'intéresser, si y'a pas de problème de doublets.
    Je connais pas cette posibilité de fusionner des libs. Si ça marche, je l'adopte.
    C'est l'option "additional dependencies" dans Liberian?

    Regarde un truc genre #pragma comment (lib:...)
    Souvent, le compilatuer définira des macros préprocesseur (genre DLL).
    Je vais tâcher de voir ça demain.

  14. #34
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Mes essais ne sont pas concluants, et donc j'ai encore des questions.

    1)
    J'ai pas trouvé le moyen de fusionner/aggréger des libs statiques. J'ai bien essayé l'option 'additional dependencies' dans l'onglet Liberian, pour inclure la librairie statique de STLport. Mais lors de l'édition de lien du programme utilisateur, ma librairie impose encore la dépendance envers la lib statique de STLport.

    2)
    C'est bien "#pragma comment (lib: )" pour importer des libs dans le code source.
    Et j'ai effectivement trouvé la macro _DLL, définie par Visual lorsque le code généré est en "Multithreaded DLL" (/MD, /MDd).
    Mais cette macro ne permet pas de savoir si le compilo génère ou non une DLL. Car il est tout-à-fait possible de faire une librairie statique en MD !!!, comme il est possible de faire une librairie dynamique en MT/ML !!!
    Je pense avoir une idée de ce qu'est la géneration single/muti threaded (ML/MT), mais je comprends donc plus à quoi sert le multithreaded DLL.

  15. #35
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Pour ta question 2, c'est en fait à quel runtime on va lier ta bibliothèque. Ce runtime contient en gros la bibliothèque standard, et on peut l'avoir en version statique ou dynamique, en version monothread - plus rapide - ou multithread - quand on utilise les threads -

  16. #36
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Charlemagne
    1)
    J'ai pas trouvé le moyen de fusionner/aggréger des libs statiques. J'ai bien essayé l'option 'additional dependencies' dans l'onglet Liberian, pour inclure la librairie statique de STLport. Mais lors de l'édition de lien du programme utilisateur, ma librairie impose encore la dépendance envers la lib statique de STLport.
    Désolé, je ne peux pas vraiment t'aider, puisque comme je l'ai dit, je n'ai jamais vraiment utilisé ce truc. Peut-être permet-il juste d'éviter à l'utilisateur de devoir spécifier dans son projet qu'il a besoin de l'autre bibliothèque, mais ne permet pas d'éviter qu'elle soit fournie ?

    Le dernier conseil que je peux donner, c'est d'utiliser dumpbin.exe(http://msdn2.microsoft.com/fr-fr/library/756as972.aspx) pour deboguer les symboles présents dans une lib.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. Comment lier un Button Item avec une Image d'un base SQL
    Par Badouba76 dans le forum Développement iOS
    Réponses: 2
    Dernier message: 13/11/2013, 17h22
  2. Réponses: 4
    Dernier message: 28/01/2009, 13h59
  3. comment créer un rpm à partir d'une lib source
    Par kris1 dans le forum Applications et environnements graphiques
    Réponses: 1
    Dernier message: 06/12/2007, 18h35
  4. Réponses: 6
    Dernier message: 26/09/2007, 01h03
  5. Comment lier les sources d'une lib à son nom ?
    Par nutzzz dans le forum Autres éditeurs
    Réponses: 3
    Dernier message: 20/09/2007, 10h51

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