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 :

MinGW, DLL externe, DEF, LIB, a. Je sèche.


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 26
    Par défaut MinGW, DLL externe, DEF, LIB, a. Je sèche.
    Bonjour.
    Pour un de mes projets écrit avec code::blocks + wxWidget + MinGW, tous dans leur version récente, je dois faire appel à des fonctions disponibles dans une DLL fournie par un tiers.
    Je dispose du fichier DLL, du fichier .h des fonctions disponibles, du fichier LIB, et après quelques efforts, j'ai réussi à extraire le fichier DEF avec l'outil dlltool de MinGW32

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    LIBRARY "EQ2008_Dll.dll"
    EXPORTS
    User_CloseScreen@@YGHH@Z
    User_ReadScreen@@YGHHPAUHDC__@@@Z
    Je n'arrive pas à linker correctement cette DLL dans mon projet. L'édition de lien me donne systématiquement une erreur à chaque appel de fonction dans la DLL: undefined reference to `_imp___Z16User_CloseScreeni@4'
    Mon projet est compilé avec MinGW, donc j'utilise des fichiers .a pour linker, alors que la DLL est livré avec un fichier.LIB
    Ce que j'ai essayé:
    - renommer le .LIB en .a: ne marche pas
    - inclure la DLL dans les bibliothèque à linker (avec les autres .a du projet): ne marche pas
    - extraire de la DLL le .a avec reimp.exe: ne marche pas. J'obtiens un .a vide

    Bref, je sèche. Avant de modifier le projet pour appeler directement les fonctions en lisant la DLL en dynamique lors de l'exécution (mon plan B !), j'aimerai savoir si vous avez des idées sur mon problème ?
    Comment convertir un .LIB ou .def en .a compatible avec MinGW ?
    Peut-on dans code::blocks directement linker une DLL sans le .a ?

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Normalement, si tu as réussi à obtenir le fichier def, il te "suffit" d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dlltool -k --outputlib libEQ2008_Dll.a --def lefichier.def
    (j'ai utilisé le nom de la dll comme base pour le nom du fichier *.a ) pour créer une bibliothèque d'importation.

    Il faudra, par la suite, veiller:
    1. à ce que gcc (g++ ) connaisse le chemin d'accès aux fichiers d'en-tête en ajoutant l'argument (c'est un i majuscule )à la ligne de commande (ou en ajoutant le dossier en question dans les options de Code::Blocks)
    2. à ce que ld (l'éditeur de liens) connaisse le chemin d'accès au dossier contenant le lib*.a en ajoutant l'argument
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      -Lchemin/vers/dossier/de/lib
      à la ligne de commande (ou en ajoutant le dossier en question dans les options de Code::Blocks)
    3. veiller à ce que ld (toujours l'éditeur de liens ) effectue bien l'édition de lien avec la bibliothèque en question en ajoutant l'argument (c'est un L minuscule ) à la ligne de commande ou en ajoutant la bibliothèque en question dans les options de Code::Blocks)
    4. à ce que l'exécutable puisse accéder à la dll, soit en la plaçant dans le même dossier de l'exécutable, soit en la plaçant dans un dossier connu de la variable PATH
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 26
    Par défaut Merci de te pencher sur mon problème..
    Citation Envoyé par koala01 Voir le message
    Salut,

    Normalement, si tu as réussi à obtenir le fichier def, il te "suffit" d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dlltool -k --outputlib libEQ2008_Dll.a --def lefichier.def
    (j'ai utilisé le nom de la dll comme base pour le nom du fichier *.a ) pour créer une bibliothèque d'importation.
    Justement, c'est là où j'ai un problème.
    Bien sûr, le fichier EQ2008_Dll.def existe dans le répertoire de dlltool et est rempli avec les définitions.
    Lorsque j'entre cette commande
    dlltool -v -k -d EQ2008_Dll.def -l EQ2008_Dll.a
    ,j'ai bien un fichier EQ2008_Dll.a qui est créé, mais il est vide. Taille: 0K, et ouvert avec Notepad++, pas un seul petit octet à lire....
    Même chose en essayant la version de dlltool dans mingw32.
    Je pense que si j'arrive à obtenir un fichier .a non-vide, j'aurai progressé, mais là quelque chose m'échappe.
    Bien sûr, le fichier EQ2008_Dll.def existe dans le répertoire de dlltool et est rempli avec les définitions.
    Le fichier complet (avec -v) est celui-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    dlltool: Processing def file: EQ2008_Dll.def
    dlltool: LIBRARY: EQ2008_Dll.dll base: ffffffff
    dlltool: Processed def file
    dlltool: Processing definitions
    dlltool: Processed definitions
    dlltool: Creating library file: EQ2008_Dll.a
    dlltool: run: as   -o daqh.o daqh.s
    dlltool: No such file or directory
    dlltool: CreateProcess
    Après vérification, le fichier .s est bien créé, mais pas le .o

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Attention, une bibliothèque lib*.a n'est absolument pas un fichier que l'on peut ouvrir avec notepad...

    Il s'agit, en réalité, d'une archive (créée avec ar), que l'on peut, éventuellement, ouvrir avec 7zip ou winrar, qui contient un certain nombre de fichiers objets ( *.o ).

    Ceci dit, en créant le fichier eq2008_Dll.def sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    LIBRARY "EQ2008_Dll.dll"
    EXPORTS
    User_CloseScreen@@YGHH@Z
    User_ReadScreen@@YGHHPAUHDC__@@@Z
    et, en lançant la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dlltool.exe -k --output-lib libeq2008_dll.a --def eq2008_dll.def -v
    j'obtiens la sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    c:\temp-32bits\bin\dlltool.exe: Using file: c:\temp-32bits\bin\as
    c:\temp-32bits\bin\dlltool.exe: Processing def file: eq2008_dll.def
    c:\temp-32bits\bin\dlltool.exe: LIBRARY: EQ2008_Dll.dll base: ffffffff
    c:\temp-32bits\bin\dlltool.exe: Processed def file
    c:\temp-32bits\bin\dlltool.exe: Processing definitions
    c:\temp-32bits\bin\dlltool.exe: Processed definitions
    c:\temp-32bits\bin\dlltool.exe: Creating library file: libeq2008_dll.a
    c:\temp-32bits\bin\dlltool.exe: run: c:\temp-32bits\bin\as   -o dyskh.o dyskh.s
    c:\temp-32bits\bin\dlltool.exe: run: c:\temp-32bits\bin\as   -o dyskt.o dyskt.s
    c:\temp-32bits\bin\dlltool.exe: Creating stub file: dysks00000.o
    c:\temp-32bits\bin\dlltool.exe: Creating stub file: dysks00001.o
    c:\temp-32bits\bin\dlltool.exe: Created lib file
    et un fichier libeq_2008_dll.a de 4 ko octets contenant (ouvert avec 7zip), effectviement les fichiers objets
    • dyskh.o
    • dyskt.o
    • dysks00000.o
    • dysks00001.o
    Ce résultat est obtenu à partir de la version "personnelle" de dlltool compilée a mano:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     dlltool.exe -V
    GNU c:\temp-32bits\bin\dlltool.exe (GNU Binutils) 2.20.51.20100125
    Copyright 2010 Free Software Foundation, Inc.
    This program is free software; you may redistribute it under the terms of
    the GNU General Public License version 3 or (at your option) any later version.
    This program has absolutely no warranty.
    Nota: le fichier *.def utilisé est écrit au format *nux (fin de ligne marqué avec lf)

    Il y a, effectivement, un problème si le fichier est au format DOS (fin de ligne signalé par CRLF)...

    As tu essayé en créant le fichier def avec gendef qui semble éviter ce problème
    [EDIT]Il ne faut pas de fichier *.s... il s'agit de l'extension utilisée pour la création de fichier assembleur temporaire, utiles à la création des fichiers objets
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 26
    Par défaut Je progresse..
    Merci de votre aide.J'avance.
    Mais je ne suis pas encore au bout..

    Mon problème pour générer le .a venait de deux installations de dlltool, toutes deux visibles par PATH. Je suppose que as.exe s'emmêlait les pinceaux.

    Maintenant, j'ai mon .a que je link avec mon projet.
    Mais toujours cette erreur:
    undefined reference to `_imp___Z15User_OpenScreeni@4'

    Le fichier .h de la DLL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define DLL_API _declspec(dllimport)
    DLL_API BOOL __stdcall User_OpenScreen(int CardNum);
    Mon appel à la fonction dans mon projet cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    User_OpenScreen(m_CardNum);
    Rappel: Le contenu du .def
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    LIBRARY "EQ2008_Dll.dll"
    EXPORTS
    User_OpenScreen@@YGHH@Z
    et enfin la commande ayant servi à générer le .a:
    dlltool -v -k -d EQ2008_Dll.def -l EQ2008_Dll.a

    Je soupconne qu'il s'agit d'une différence au niveau du nom de ma fonction, mais je ne suis pas assez calé pour trouver l'erreur.
    Je vais poser la question dans la section bibliothèque du forum (j'ignore comment transférer ce post dans ce forum)

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    As tu bien spécifié les options d'édition de liens qui étaient nécessaires (-Lchemin/vers/libEQ2008_Dll.a -lEQ2008_dll en ligne de commande ou project->build options-> linker settings ->ajouter EQ2008_dll + project->build options->search directories->linker ->ajouter le chemin vers libEQ2008_Dll.a, dans Code::blocks)

    Généralement, une référence indéfinie est le signe que l'éditeur de liens n'a pas effectué la liaison avec une bibliothèque requise.

    Cela arrive soit parce qu'il ne sait pas qu'il doit utiliser la bibliothèque en question, soit parce qu'il ne la pas trouvée dans les dossiers dans lesquels il a regardé
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. DLL sans .DEF ou .LIB
    Par ZJP972 dans le forum C
    Réponses: 3
    Dernier message: 05/07/2007, 21h40
  2. Appel de DLL sans .DEF ou .LIB
    Par ZJP972 dans le forum C++
    Réponses: 5
    Dernier message: 05/07/2007, 21h35
  3. dll ActiveX utilisant une DLL externe
    Par Metal3d dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 10/11/2005, 18h02
  4. [Jonas]Ajout de dll externes
    Par romainp22 dans le forum JOnAS
    Réponses: 8
    Dernier message: 14/01/2005, 11h41
  5. Dialogue DLL externe
    Par rgarnier dans le forum XMLRAD
    Réponses: 8
    Dernier message: 07/05/2003, 14h28

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