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 :

[windows] charger une dll (avec classe)


Sujet :

Windows

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 32
    Points : 11
    Points
    11
    Par défaut [windows] charger une dll (avec classe)
    bonjour,

    tout dabord je precise que je sais comment charger une dll
    si je ne me trompe pas, il y'a 2 cas :
    1) vous avez le .lib, vous linké et vous charger avec dllimport (borland) ou sans rien sous vs2005
    2) vous avez pas le .lib et là, la seule solution et d'utiliser LoadLibrary(); GetProcAddress(); FreeLibrary();

    voila, je m'intersse au second cas.

    vous devez avoir une declaration pour chaque fonction presente dans la dll sous la forme d'un .h ou déclarer directement avec typedef.
    exemple:

    #include <windows.h>
    #include <string.h>
    #include <stdio.h>

    // FCTX is a pointer to a function waiting an int, char * etc.
    typedef int __stdcall (*FCTX)(int hWnd, char *Texte, char *Titre, unsigned int Type);

    int main (int argc, char *argv[]) {

    static char ModPath[255]="c:\\windows\\system32\\";
    int Status;
    FCTX Fn_Ptr;
    HMODULE ModId;

    strcat(ModPath, "user32.dll");
    ModId = LoadLibrary(ModPath);

    Fn_Ptr = (FCTX)GetProcAddress(ModId, "MessageBoxA");

    Status = Fn_Ptr(0, "Le texte de la boite de dialogue", "Le titre", MB_OK);

    FreeLibrary(ModId);

    return 0;
    }
    le probleme ici (meme pas de fichier header...), est que vous devez déclarer toute les fonction puis les relier aux fonction de la dll par GetProcAddr().

    Ma question est:
    Serait-il possible de creer une classe qui se chargerais de faire se travail ?
    exemple:
    #include "user23dll_decl.h"
    #include "easydll.h"

    int main()
    {

    easydll* user32dll = new easydll("c:\\windows\\system32\\user32.dll");
    user32dll->MessageBox(0, "Le texte de la boite de dialogue", "Le titre", MB_OK);
    delete user32dll;

    return 0;

    }
    (avec les fonction déclaré dans user32dll_decl.h)

    Existe-il une telle classe (easydll dans lexemple) ?
    Est-elle a priori possible a faire ?

    merci.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    • Une classe absolument polyvalente ? Non.
    • Une classe dédiée à une DLL ? Oui.

  3. #3
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    Il doit être possible de faire une classe assez générique, mais pas forcément pratique ou tu aurais des appels du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    func_type func = easydll.getFunc<func_type>(func_name);
    func(...);
    Mais après c'est à toi de déclarer le type de chaque fonction que tu veux récupérer.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 32
    Points : 11
    Points
    11
    Par défaut
    merci pour vos reponses.

    Par contre je ne connais que assez peu les subtilitées du c++,
    quand MatRem ecrit :
    easydll.getFunc<func_type>(func_name);

    easydll : classe
    getfunc : methode de la classe
    (func_name) : parametre de la mathode

    mais a quoi correspond <func_type> ???

    merci.

  5. #5
    Membre éclairé Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Points : 693
    Points
    693
    Par défaut
    C'est un paramètre template, la classe serait définie de cette façon (pour la partie de la fonction) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class EasyDll
    {
    public :
       template<typename type_func>
       type_func getFunc(const std::string & funcName);
       ...
    };
    Je te conseille de regarder comment fonctionne les template :
    http://c.developpez.com/faq/cpp/?page=templates
    http://c.developpez.com/tutcpp/c4369.php

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 32
    Points : 11
    Points
    11
    Par défaut
    bien, les vacances sont passé.

    pour l'instant j'ai donc sa :
    main:
    extern "C" typedef int __stdcall (*retourne1000)();
    int main()
    {
    DllImport* dll2test = new DllImport("dll2test.dll");
    printf("%d\n",dll2test->getFunc<retourne1000>("retourne1000"));
    ...
    }
    dllimport.cpp
    #include "dllimport.h"

    DllImport::DllImport(char* _dllpath)
    {
    strcpy(dllpath,_dllpath);
    hmod = LoadLibrary(dllpath);
    }
    DllImport::~DllImport()
    {
    FreeLibrary(hmod);
    }
    template<typename type_func> type_func DllImport::getFunc(char* szFctName)
    {
    return (type_func)GetProcAddress(hmod, szFctName);
    }
    dllimport.h
    class DllImport
    {
    private:
    HMODULE hmod;
    char dllpath[256];
    public:
    DllImport(char* _dllpath);
    ~DllImport();
    template<typename type_func> type_func getFunc(char* szFctName);

    };
    le compilateur me sors :
    main.cpp:9: undefined reference to `int (*DllImport::getFunc<int (*)()>(char*))()

    et j'avoue etre un peu perdu .
    Es-ce qu'il est possible de passer un pointeur de fonction en parametre template ? car je n'ai pas vu sa sur google.

    Dans l'exemple de MatRem j'ai du mal a comprendre la réference '&'
    type_func getFunc(const std::string & funcName);

    si quelqu'un a des ptit conseil ou autre, merci.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Le extern "C" n'a rien à faire dans le typedef.
    Et les fonctions templates doivent être définies dans le .h, comme des fonctions inline.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 32
    Points : 11
    Points
    11
    Par défaut
    en effet la methode template dans le .h sa a l'air de mieu marcher
    ( extern "C" car les fonction sont definis dans la dll .)

    pour ma fonction retourne1000 sa marche et cela me retourne bien 1000

    extern "C"
    {
    // dll2test
    typedef int __stdcall (*retourne1000)();
    typedef char* __stdcall (*toupperpok)(char* str);
    }

    int main()
    {
    DllImport* dll2test = new DllImport("dll2test.dll");
    printf("%d\n",dll2test->getFunc<retourne1000>("retourne1000"));
    printf("%s\n",dll2test->getFunc<toupperpok>("toupperpok")); // besoin de passer le parametre (char* str) ici

    delete dll2test;
    return 0;
    }
    Par contre je ne vois vraiment pas comment passer le parametre (char* str)
    a ma methode getFunc.
    car deja le nombre de parametre est variable ...
    et j'ai l'impression que l'on ne peut pas faire :
    template<typename type_func()>

    template<typename type_func>
    type_func getFunc(char* szFctName)
    {
    type_func myfunc = (type_func)GetProcAddress(hmod, szFctName);
    return (type_func)myfunc(); // parametre doit se trouver entre les ()
    }
    une fois ce probleme reglé j'aurais termine

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 422
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 422
    Points : 20 585
    Points
    20 585
    Par défaut
    pourquoi veux tu définir une classe template pour passer une fonction générique ?
    C'est totalement inutile et un peu lourd.
    Il suffit tout simplement de passer un pointeur VOID ou LPVOID
    Regarde les API auxquelles on passe des pointeurs de fonctions comme _beginthread par exemple

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 32
    Points : 11
    Points
    11
    Par défaut
    pour le template je suis d'accord c'est un peu inutil ,
    le extern "C" car les fonction sont dans la dll. (donc c'est obligatoire)

    par contre j'ai beau essayer de faire marcher un code comme sa :
    void* getFunc(char* szFctName,void* (*func_type)(void* arg))
    {
    func_type myfunc = (type_func)GetProcAddress(hmod, szFctName);
    return (type_func)myfunc(arg);
    }
    rien n'y fait j'ai des erreur de syntax ou alors je me trompe completement dans la maniere de jouer.

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 32
    Points : 11
    Points
    11
    Par défaut
    Ayé j'ai trouvé grace a un coup de main.

    template<typename T> inline T *
    getFunc(const char *name)
    {
    return (T *)GetProcAddress(hmod, name);
    }
    pour ceux que sa interesse d'utiliser ma classe:
    http://jaiatech.free.fr/dllimport.zip

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Citation Envoyé par superpok Voir le message
    le extern "C" car les fonction sont dans la dll. (donc c'est obligatoire)
    Moult te goures : extern "C" ne sert à rien pour des typedefs.

    extern "C" ne sert que pour le nom "compilé" des fonctions. Il doit être utilisé pour chaque fonction de la DLL pour être accessible via le C et facilement via GetProcAddress(), mais c'est tout...

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

Discussions similaires

  1. [WD20] Utilisation d'une DLL avec classes
    Par Invité dans le forum WinDev
    Réponses: 11
    Dernier message: 05/02/2015, 17h45
  2. Charger une dll avec MinGW
    Par bertrand125 dans le forum C++
    Réponses: 6
    Dernier message: 24/10/2012, 01h44
  3. charger une dll avec un .lib
    Par Nehmé dans le forum Visual C++
    Réponses: 13
    Dernier message: 26/08/2009, 15h26
  4. Charger une dll (api windows)
    Par zenux dans le forum C++
    Réponses: 3
    Dernier message: 11/12/2007, 12h59
  5. charger une DLL avec paramètres
    Par cyberchand dans le forum C#
    Réponses: 6
    Dernier message: 29/05/2007, 17h28

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