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 :

Utiliser une DLL sans les headers


Sujet :

C++

  1. #1
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut Utiliser une DLL sans les headers
    Bonjour,

    Voilà, j'ai un big projet de C++, basé sur des libs openSource.
    Pour effectuer un travail, je dois exporter mon projet en DLL de maniere à mettre a disposition le code du projet, mais pas son contenu.

    En d'autre mots, le projet n'est pas open source, mais il faut que je mette à disposition d'un autre projet MSVC les méthodes et classes que j'ai implémenté dans mon projet.
    En gros, j'ai codé une boite à outils et je veux donc mettre a disposition les méthodes, mais pas leur contenu.


    J'ai créé un projet vide avec quelques méthodes pour faire un essais et ça marche tres bien.


    Probleme : je voudrais donc exporter mon projet en DLL (no pb) et le livrer avec les .h necessaire. Cependant, je ne peux pas livrer tous les .h, car nombre d'entre eux contiennent beaucoup de code. De plus livrer tous les header reviens à donner toute la structure du projet...

    Sauriez vous s'il est possible dans un 1er temps, de ne pas livrer toutes les DLL, mais juste celles qu'on veut (et quelques dépendances nécessaires j'imagine) ?

    Dans mes premiers essais, j'ai pleins de soucis de compilation au linker qui ne trouve pas les méthodes visiblement, malgré le .lib et tous les headers... (error LNK2019: symbole externe non résolu ...)
    Vous auriez des idées ? des expériences ?

    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  2. #2
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Bonjour,

    J'ai progressé et j'ai enfin réussi à compiler un nouveau projet sur la base de la DLL.

    a présent, je suis en train d'essayer d'épurer la liste des .h à devoir livrer avec la DLL, mais visiblement, il les faut presque tous !

    Quel autre moyens a-t-on de livrer une DLL sans devoir livrer les header avec ?
    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  3. #3
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    Salut,
    Sans les headers c'est impossible!!!
    Le code client n'aura aucune référence de tes objets ou méthodes.

  4. #4
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Bonjour,

    Le but c'est de mettre à disposition du code, en minimisant son "dévoilement" et en ne rendant accessible qu'une poignée de classes/méthodes.

    J'ai tenté le classique DLL+.lib+headers, qui bien sur ne me convient pas.
    J'ai aussi testé le link en explicit (charger directement la dll et récuperer les pointeurs de méthodes) ce qui marche tres bien mais reste problematique car lorsque je récupere une instance d'une classe de la DLL, il me faut son header pour acceder aux méthodes... et on retombe dans le probleme original.

    J'ai vu qu'il existait 2 méthodes d'utilisation d'une DLL

    cette méthode ci :
    http://msdn.microsoft.com/en-us/libr...z7(VS.80).aspx semble ne necessiter que la DLL, sans rien d'autre... qqun a déjà essayé ? des avis sur cette méthode ?

    merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  5. #5
    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,

    c'est un peu dangereux mais on peut faire ça via le "explicit runtime linking". Je ne l'ai jamais mis en pratique, donc je ne rentrerais pas dans les détails, mais en gros, une fois que ta dll est compilée, le code qui l'utilise va ressembler à cela (exemple pour windows):

    Code : 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    // supposons que ta dll fournit une fonction qui est déclarée ainsi:
    // double AddNumbers( double a, double b );
     
    #include <windows.h>
    #include <iostream>
     
    // dignature de la fonction de ta dll
    typedef double (*importFunction)(double, double);
     
    int main(int argc, char **argv)
    {
    	importFunction addNumbers;
    	double result;
     
    	// chargement de la dll
    	HINSTANCE hinstLib = LoadLibrary(TEXT("madll.dll"));
    	if (hinstLib == NULL) {
    		std::cout << "ERROR: unable to load DLL" << std::endl;
    		return 1;
    	}
     
    	// récupération d'un pointeur sur la fonction
    	addNumbers = (importFunction)GetProcAddress(hinstLib, "AddNumbers");
    	if (addNumbers == NULL) {
    		std::cout << "ERROR: unable to find DLL function" << std::endl;
    		FreeLibrary(hinstLib);
    		return 1;
    	}
     
    	// appel de la fonction
    	result = addNumbers(1, 2);
     
    	// libératino de la dll
    	FreeLibrary(hinstLib);
     
    	return 0;
    }
    « 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

  6. #6
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Bonjour

    J'ai ce code ci, et il fonctionne.

    Il m'est donc possible d'appeler une fonction dans la ma dll.

    Par contre, en terme de gestion objet, je peux créer une instance de classe depuis une méthode, mais je récupere donc un myClass*, et je ne peux pas utiliser le myClass en question, sans avoir un .h qui défini cette classe, meme si elle est déjà définie dans la DLL ... non ?

    (heuu ce n'est peut etre pas tres clair, je vais préciser)

    En gros, je veux non seulement apeller des méthodes de la DLL, mais aussi pouvoir instancier des classes. Comme je ne peux apeller que des méthodes, je fait donc une méthode qui me retourne un new myClass().
    Je peux donc créer une instance de myClass depuis mon exe juste avec la DLL. Par contre, dans mon exe, le type myClass n'est pas défini, et donc je ne peux pas acceder à ses méthodes...

    Une idée sur comment feinter ? je commence à secher sur la question petit à petit...

    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  7. #7
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Bon, petit UP pour signaler que j'ai trouvé un moyen, certe peu glorieux, mais qui marche !

    Je créé donc dans ma DLL une méthode qui me retourne un nouvelle instance de ma classe.

    Depuis mon exe, j'appelle donc explicitement cette méthode que je récupere dans un myClass*. Le compilateur ne connait pas cette classe, je le feinte donc en déclarant la classe
    en début de fichier.

    Ainsi le compilo connait le type, mais pas les méthodes.

    Ensuite, pour acceder aux méthodes de la DLL, je créé dans la DLL une méthode qui prend en parametre mon instance de myClass et qui fera donc les appels depuis cette instance sur les fonctions membre de mon choix. Comme dans la DLL myClass est bien défini, alors tout roule

    La limite de la chose est bien sur qu'il faut redéfinir dans la DLL un certain nombre de fonctions pour permettre d'acceder aux méthodes membre, mais visiblement ça marche plutot bien.

    Je n'ai pas encore aboutit mon codage, mais j'ai enfin réussi à lancer mon code de la DLL sans .h ni rien d'autre que ma simple DLL.

    Toujours à la recherche d'autre moyens plus "clean" bien sur, mais en attendant j'ai un résultat.

    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  8. #8
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    Bonjour,
    Une solution serait peut-être de réencapsuler tes classe pour en cacher l'implémentation, comme expliqué ici:
    http://bruce-eckel.developpez.com/li...ntation#L5.6.2
    ou ici:
    http://www.gotw.ca/gotw/028.htm

    Ainsi tu aura surement moins de header a fournir. Et des header plus petit.

  9. #9
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    C'est en effet une solution potentielle, et c'est aussi ce que j'utilise déjà, du mois en partie.
    Je me base sur la déclaration de classe pour ne pas avoir besoin du header complet.

    Je vais voir si l'appliquer sur le code de ma DLL peut suffire à ce que je veux, auquel cas c'est en effet plus propre comme méthode.

    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  10. #10
    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
    Si tu veux, tu peux aussi cumuler les chargements explicites et les classes abstraites pures, en exportant juste les fonctions qui créent un nouvel objet sur le tas (et celles qui détruisent).

    Ou à l'extrême, en faire une DLL COM.
    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.

  11. #11
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Si tu veux, tu peux aussi cumuler les chargements explicites et les classes abstraites pures, en exportant juste les fonctions qui créent un nouvel objet sur le tas (et celles qui détruisent).
    C'est une solution qui marché déjà en effet, mais si je peux éviter la DLL en explicit c'est qd meme preferable...
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  12. #12
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    UP :
    J'ai utilisé le link en explicit finalement, ce qui me dispense de toute dépendance.

    Cependant, j'ai un autre petit soucis :

    Je créé dans la DLL une instance de classe, et sur la demande de l'EXE, je récupere cette instance. Cependant l'adresse que je récupere pointe sur un truc invalide.
    J'utilise OpenSceneGraph, et donc je chercher a faire passer un osg::Group créé dans ma DLL vers mon EXE pour ensuite utiliser ce group... mais pas moyen, il me retourne tjrs un group incohérent...

    Une petite idée neuve sur ces elements ci ?

    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  13. #13
    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
    Si la DLL utilise des trucs de la C Run-Time Library et que toi tu es linké en static, en effet, des erreurs de ce genre peuvent survenir. Car maintenant, tu as deux CRT différentes dans le même processus...
    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
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Heuu je viens d'éditer en fait.

    Je link en explicit en loadant la DLL et en récuperant les adresses des fonctions.

    Le soucis c'est de passer des adresses d'elements communs aux deux (DLL et EXE utilisant la DLL)...

    Ta remarque est t elle toujours valide avec cette "correction" de ma part ?
    (car je comprend pas trop cette histoire de runTime...)

    Merci.
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  15. #15
    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
    Non, ma remarque n'est plus valide.
    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.

  16. #16
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Bé figure toi que moi j'ai le problème inverse. Dans mon boulot, on me fournit des DLL, avec que des méthodes, j'ai aucun moyen de savoir comment ils se débrouillent dans leur code.

    Ce qu'ils font, c'est qu'ils gèrent tout par Handle. Une fonction va créer une classe, et renvoyer un handle. Pour manipuler cette classe, il faut appeler une fonction, globale (donc pas sur la classe) mais en lui passant son handle.

    Ainsi, ils exposent une seule classe (juste pour encapsuler des fonctions de manipulation) dans un .h qui manipulent les données sans exposer leurs type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CLibrary lib = new CLibrary(); // Instancie la seule classe exposée, de manip, ça fait un LoadLibrary derrière
    long hClass = lib.CreateClass(...); // Un getProcAdress
    lib.FaitFaireQuelquechoseALaClasse(hClass); // Puis un autre
    lib.ReleaseClass(hClass); // Et encore un autre
    En fait la classe exportée fait de la liaison dynamique pour éviter à l'utilisateur de la lib à le faire lui même, à connaître le nom des méthodes etc... Comme ça il peut bosser avec intellisence tranquillement.
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  17. #17
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    C'est exactement ce que j'ai fait

    Comme ça intellisence n'est pas perdu, et il suffit d'avoir un header et une DLL pour que tout roule...
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

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

Discussions similaires

  1. Création d'une DLL sans les sources (.c)
    Par joks93440 dans le forum Débuter
    Réponses: 10
    Dernier message: 12/11/2013, 17h06
  2. Utiliser une fonction d'une DLL sans l'extraire
    Par Coussati dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 01/10/2011, 09h52
  3. Réponses: 2
    Dernier message: 20/05/2011, 12h01
  4. Afficher la ligne entière dans une listView Sans les headers
    Par Msysteme dans le forum Windows Forms
    Réponses: 2
    Dernier message: 26/02/2009, 12h56
  5. Utiliser une DLL sans le .LIB dans Visual Studio 2005
    Par lekernel dans le forum Visual C++
    Réponses: 5
    Dernier message: 02/08/2007, 08h54

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