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

Windows Discussion :

Créer une dll Windows (de stockage ressource) ?


Sujet :

Windows

  1. #1
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut Créer une dll Windows (de stockage ressource) ?
    Bonjour,

    Toujours pour m'informer afin de créer une nouvelle version, carrément propre, de ma prochaine version d'un lecteur audio, j'ai décidé de me renseigner sur la manière de stocker mes fonctions d'affichages (celle que j'ai trouvé par exemple sur internet permettant de créer une région à partir d'un bitmap) ainsi que les différents skins de mon lecteur (des icônes, images etc.).

    Je pense que le plus approprié reste la DLL, mais je ne sais que créer une dll simple, permettant de stocker des fonctions, et encore je trouve cela un peu (beaucoup) basique. (est-ce vraiment comme cela ?)
    Voici la méthode trouvée :
    ** [Code::Blocks] New project -> Dynamic Link Library **

    Dll.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <math.h>
    
    double __declspec(dllexport) FoisDixPuissance(double nombre, int puissanceDeDix)
    {
       return nombre * pow(10,puissanceDeDix);
    }
    ** Build **

    Résultat : Une dll, ainsi qu'un .lib ou .a

    Puis, dans le programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //includes
    
    double __declspec(dllimport) FoisDixPuissance(double nombre, int puissanceDeDix);
    Pourriez vous m'éclairer ?

    Merci d'avance.

    [edit] J'ai trouvé cela, mais comment faire pour que la dll soit mixte ?
    Pourriez vous par ailleurs me donner un petit exemple de code source chargeant la dll, et quelques fichiers ? J'ai besoin de quelques exemples...
    Vive l'embarqué.

  2. #2
    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
    Déjà, ta DLL devrait avoir un fichier d'en-tête mixte. Généralement, on prend ce que donne Visual:
    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
    #ifdef BUILDING_NOMDELADLL
    #define NOMDELADLL_API __declspec(dllexport)
    #else
    #define NOMDELADLL_API __declspec(dllimport)
    #endif
    
    #ifdef __cplusplus
    extern "C" 
    {
    #endif
    
    NOMDELADLL_API double FoisDixPuissance(double nombre, int puissanceDeDix);
    
    #ifdef __cplusplus
    }
    #endif
    Ici, c'est la partie du haut qui nous intéresse, elle définit la macro NOMDELADLL_API.
    Pour que le code soit construit correctement, tu dois définir BUILDING_NOMDELADLL dans le projet de la DLL, pour qu'elle soit compilée avec dllexport...



    Pour les DLLs avec des ressources, c'est simple : Il te suffit d'ajouter des ressources au projet de la DLL.
    Ces ressources doivent ensuite être chargées avec le HMODULE de la DLL (pour un LoadBitmap() par exemple, tu passes le HMODULE dans le paramètre hInstance. Aucun cast n'est nécessaire, il y a un typedef de HMODULE sur HINSTANCE).
    Si tu veux charger ces ressources depuis l'EXE, le HMODULE de la DLL peut être obtenu au retour de LoadLibrary() ou en appelant GetModuleHandle("nomdeladll").
    Si tu veux les charger depuis la DLL, le meilleur moyen est de définir la fonction DllMain() et de profiter de l'événement DLL_PROCESS_ATTACH pour mémoriser le HMODULE dans une variable globale...
    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.

  3. #3
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Je ne suis pas sous Visual, mais je suppose que c'est la même chose pour le reste...

    Suis-je obligé de faire les directives de préprocesseur données ? C'est à dire, __declspec(dllexport) n'est-il pas toujours utilisé, ce qui rendrait l'autre inutile ?

    Sinon, pour la récupération, je pensais la faire dans le code de l'exécutable, mais savoir le faire pour la dll est bon à savoir

    Donc si je récapitule, dans le code source de l'exéctable je dois faire :
    1. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      HMODULE hmLibrary = LoadLibrary("Libraries\\Library.dll");
    2. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      HBITMAP hBmp = LoadBitmap(hmLibrary, "monBitmap"); /* Où monBitmap est l'identifiant ressource dans Library.dll */
    3. Code : Sélectionner tout - Visualiser dans une fenêtre à part
      FreeLibrary(hmLibrary);


    Sinon, je n'arrive pas à savoir à quoi sert DllMain... elle est sûrement appelée dès le chargement, mais je trouve cela inutile pour les intéractions avec l'exécutable, à part si, dans une fonction de cette dll je charge un bitmap directement, et à l'appel de la fonction celle ci retourne le bitmap... mais bon.

    Q'en penses tu ?

    [edit] Je me suis renseigné sur msdn sur la façon que tu m'as donné, et c'est vrai que l'on peut faire comme cela mais est-ce vraiment avantageux ? Après c'est une question de goûts je suppose... je verrais en temps voulu.

    Sinon, est-ce qu'une bibliothèque statique observe le même code ? Si non, lequel est-ce ?

    [reedit] J'ai beaucoup de questions, je sais :p Dois-je refaire un sujet pour savoir à quoi sert un hook ? C'est une dll, d'accord, mais qu'a-t-elle de spécial ?
    Vive l'embarqué.

  4. #4
    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
    1. Pour les #define, ça permet d'utiliser le même header pour compiler la DLL et pour l'utiliser.
    2. DllMain() sert surtout dans la DLL à initialiser des données globales au process (notamment, des index de Thread-Local Storage) et mémoriser le HMODULE de la DLL.
    3. Je ne sais pas si le bitmap est encore valide après le FreeLibrary() : Je n'ai pas testé...
    4. Pour une bibliothèque statique, rien de tout cela: Ce sont juste des fonctions.
    5. Pour les hook, je ne sais pas exactement, je n'ai pas bossé dessus... Mais certains hooks peuvent être appelés depuis n'importe quel processus, il me semble...
    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. #5
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    D'accord. Merci beaucoup pour tout cela. (pour la bibliothèque statique, je parlais efectivement des fonctions)

    Et sinon, en ce qui conçerne l'utilisation des fonctions présentes dans la Dll, comment cela marche-t-il ? Je suppose qu'après avoir chargé la dll, on ne peut pas directement les utiliser...
    Vive l'embarqué.

  6. #6
    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
    Eh bien ça dépend de la façon dont tu utilises la DLL.

    Si tu l'utilises en "Load-time dynamic linking" (encore appelée liaison implicite), tu n'as rien à faire, même pas à charger la bibliothèque toi-même : Il te suffit de lier le programme utilisateur à la bibliothèque statique d'importation générée en même temps que la DLL. C'est à cela que servent les déclarations en dllimport.
    Quant aux ressources, tu peux récuperer le HMODULE avec GetModuleHandle("NomDeLaDll")


    Si tu l'utilises en "Run-time dynamic linking" (encore appelée liaison explicite), tu fais tout toi-même: LoadLibary() pour charger la DLL, et obtenir un pointeur de fonction avec GetProcAddress().
    Note: Je conseille de définir un typedef pour ce pointeur de fonction dans le fichier d'en-tête de la DLL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef double (*FOISDIXPUISSANCEPROC)(double nombre, int puissanceDeDix);
    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.

  7. #7
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    Avec la liaison implicite, on peut tout faire d'après ce que tu dis (récupérer les ressources et les fonctions etc) alors pourquoi utiliser la liaison explicite ?
    Vive l'embarqué.

  8. #8
    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
    Parce qu'avec la liaison implicite, le programme ne démarre pas sans la DLL. Avec la liaison explicite, on peut vérifier si la DLL existe et autoriser ou non des fonctions...

    En fait, la liaison explicite est très bien pour des plug-ins. Les composants COM sont également une forme de liaison explicite, avec un enregistrement de la position des DLLs en plus.
    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.

  9. #9
    Membre régulier Avatar de kidpaddle2
    Inscrit en
    Avril 2006
    Messages
    430
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 430
    Points : 95
    Points
    95
    Par défaut
    D'accord. Merci pour tout, je crois que ce topic est désormais résolu
    Vive l'embarqué.

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

Discussions similaires

  1. [Commentez] Créer une DLL standard Windows en VB6
    Par SfJ5Rpw8 dans le forum VB 6 et antérieur
    Réponses: 15
    Dernier message: 06/01/2015, 00h16
  2. [AC-2007] Utilisation d'une dll windows personnalisée créer avec vb6
    Par samloba dans le forum VBA Access
    Réponses: 1
    Dernier message: 21/05/2010, 14h27
  3. créer une dll ressource avec vs 2005 ?
    Par trent94 dans le forum Débuter
    Réponses: 0
    Dernier message: 22/02/2010, 14h02
  4. Créer une dll enregistrable avec c:\WINDOWS\system32\regsvr32.exe
    Par Immobilis dans le forum Général Dotnet
    Réponses: 13
    Dernier message: 09/03/2009, 21h37
  5. Créer une DLL ressource
    Par ninaleo dans le forum Langage
    Réponses: 2
    Dernier message: 09/09/2008, 19h19

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