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 :

Utilisation d'une classe externe dans une DLL


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Points : 11
    Points
    11
    Par défaut Utilisation d'une classe externe dans une DLL
    Salut,

    J'ai un ptit soucis sur la mise en place d'un système de plugin pour un programme de traitement d'images.

    Depuis mon programme j'appelle une DLL qui contient une fonction 'process' ( qui va manipuler la valeur des pixels d'une ou plusieurs images).
    Jusque là pas de soucis.

    Mais lorsque j'essaye d'utiliser une classe appartenant à mon programme dans cette DLL, ça foire au moment du link :
    MaClasse* x; //Marche
    x->f(); //Link Error

    D'où ma question :
    Est-ce possible de compiler une DLL en utilisant un fichier .obj existant ( celui ou maClasse est définit ) ?
    Connaissez vous une meilleur façon de procéder ( je pensais faire une lib exprès pour cette DLL, mais ça risque d'être long surtout que suis débutant dans ce domaine ).

    Je précise que je suis sous visual studio 7.0 ( shared MFC DLL)


    Merci de m'avoir lu,

    a+



    EDIT : Bon j'ai réussi pour les obj, ça compile mais c'est vraiment vilain ( obligé de rajouter 4 fichiers obj dans additional dependencies )

  2. #2
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    il y a 2 façons, sous windows, d'utiliser du code compilé en dehors de l'application: une lib statique (.lib) ou une lib dynamique (dll). L'avantage de la première est que c'est plus confortable pour le développeur, l'avatange de la seconde est que l'on est pas contraint de recompiler l'appli lorsqu'on modifie la lib (idéal donc pour un système de patch et surtout de plug-in).

    Lorsque tu compiles ta dll, le code résultant ne comporte que le minimum d'informations concernant le contenu de cette dll, à savoir l'adresse des fonctions qui y sont implémentées. Il est donc indispensable de récupérer les adresses de ces fonctions pour pouvoir les appeler.

    Pour ce faire, il faut définir un .def dans le projet de ta dll. Ce .def définit toutes les fonctions que tu souhaites exporter. Le mieux c'est que ce .def porte le même nom que la dll générée. Ce .def va ressembler à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    LIBRARY	"MaLib"
     
    EXPORTS
        Fonction1        @1
        Fonction2        @2
    Pour charger ta dll, tu dois alors utiliser la fonction LoadLibrary(), qui te retourne un handle sur cette dll. Note: tu dois connaitre le nom et l'emplacement de cette dll pour pouvoir appeler LoadLibrary().

    Un fois cette lib chargée, tu va devoir retrouver tes fonctions en utilisant la fonction GetProcAddress, et lui donner le nom de la fonciton en paramètre. GetProcAddress retourne un pointeur sur ta fonction.

    Si tu veux récupérer une classe, il va te falloir implémenter quelque chose du style MaClasse* GetInstance(); et du coup, pas besoin d'exporter toutes les fonctions membres de ta classe.

    Il y a certainement des oublis et des erreurs dans ce que je te dis là, il y a longtemps que je n'ai plus utilisé le mécanisme des bibliothèques dynamiques, mais n'hésites pas à poser des questions.

    Hope it helps.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je pense que tu es un peu à côté.

    La méthode la plus simple pour utiliser une DLL C++, c'est de lier ton projet "utilisateur" à la bibliothèque statique d'importation créée en même temps que la DLL (ou livrée avec). Il s'agit généralement d'un fichier .lib avec le même nom que la DLL.
    L'inconvénient de cette méthode, c'est que la DLL doit absolument avoir été produite par le même compilateur, pour des raisons de name mangling.

    L'autre méthode est celle employée par COM/OLE, expliquée ici :
    [Résolu] Chargement 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.

  4. #4
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    si tu veu que ta DLL utilise un objet de ton programme, il te faut faire connaitre a celle ci l'adresse de l'objet en question grâce a un pointeur par exemple.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 11
    Points : 11
    Points
    11
    Par défaut
    Salut !

    Désolé pour ma réponse tardive , au boulot j'ai pas le net et j'ai pas trop eu le temps cette semaine.

    J'ai résolu mon problème en utilisant une petite structure commune à ma DLL et mon programme.
    C'est pas super joli niveau conception mais rapide à mettre en place ( je devais finir mon stage aujourd'hui ).


    @r0d : Merci pour ta réponse très instructive et d'avoir prit de ton temps pour me répondre.

    @Médinoc : Merci pour ces précisions ( même si mon soucis n'était pas lié à l'importation de ma DLL dans le projet ).

    @GEIIMAN : yup, et comme le disait r0d le mieux aurrait été de faire une 2eme DLL et de récupérer les adresses via GetProcAddress.


    Merci à vous,
    a+.

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc
    Je pense que tu es un peu à côté.

    La méthode la plus simple pour utiliser une DLL C++, c'est de lier ton projet "utilisateur" à la bibliothèque statique d'importation créée en même temps que la DLL (ou livrée avec). Il s'agit généralement d'un fichier .lib avec le même nom que la DLL.
    L'inconvénient de cette méthode, c'est que la DLL doit absolument avoir été produite par le même compilateur, pour des raisons de name mangling.
    Et puis, le truc c'est que lorsque l'on souhaite utiliser les dll pour faire des plugins, le chargement des dll se fait forcément à l'exécution (en général, l'application scanne un dossier et charge les dll présentes dans ce dossier) car on ne sait pas, à la compilation, quelle dlls sont à charger. La lib d'import n'est donc d'aucune utilité dans ce schéma.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je dois avouer que j'avais mal lu ton précédent post.
    En tout cas, ce que tu as dit sur le MaClasse * GetInstance() méritait de préciser que toutes les fonctions membres à importer doivent être virtuelles.
    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.

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

Discussions similaires

  1. Utilisation d'une classe C++ dans une classe C#
    Par Masmeta dans le forum C++/CLI
    Réponses: 1
    Dernier message: 01/07/2015, 21h59
  2. Réponses: 7
    Dernier message: 05/04/2011, 17h19
  3. Réponses: 21
    Dernier message: 14/01/2010, 12h50
  4. Réponses: 15
    Dernier message: 28/04/2009, 07h26
  5. Réponses: 6
    Dernier message: 30/03/2009, 18h13

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