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

Langage C++ Discussion :

Templates & methods virtuels : La feinte parfaite ?


Sujet :

Langage C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut Templates & methods virtuels : La feinte parfaite ?
    Bonjour

    Voila je rencontre un petit souci :
    Comment contourner (avec classe) l'impossibilitee de compiler des methods templates virtuels .

    Dans une cadre de l'abstraction d'un loader de .dll/.so j'ai fais une classe abstraite DLHandler qui peut avoir pour fille SOLoader ou DLLLoader etc ...

    Mais il y a un souci au niveau de la method qui abstrait dlsym et GetProcAddress (je l'appelle getFunction()).

    Man : dlsym et GetProcAddress retournent un poiteur sur la fonction contenue dans la librairie dynamique. Elle en param prend le nom de cette fonction.

    le but est de pouvoir faire ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    //type de la fonction demandee
    typedef int (*my_fct_ptr)(void);
     
    my_fct_ptr my_fct;
    DLHandler obj;
     
    //init obj ...
     
    my_fct = obj.getFunction<my_fct_ptr>("uneFctC");
    pour cela la classe abstraite DLHandler doit resembler a ca :

    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
     
    class DLHandler
    {
    private:
        type_mystere _type;
     
    //...
    public:
        DLHandler(type_mystere type)
        {
            _type = type;
        }
     
        template <typename type>
        type getFunction(const std::string name)
        {
            //appelle a la fonction contenue dans la fille en utilisant le type mystere
        }
    //...
    }
    Donc comme vous l'avez surement remarque, le souci vient du type mystere.

    J'ai donc deux solutions pour resoudre ce souci (si y'en a d'autres je suis open) :

    1) Prevoir des pointeurs sur methods dans DLHandler pour toutes les class filles possibles de DLHandler. C'est simple mais je trouve extrement moche.

    2) Je fais un poiteur sur method generique qui peut etre utilise pour toutes les classes filles. Ca c'est classe mais dans ce cas je ne sais pas faire !

    En gros on arrive a la question :
    Est il possible de faire un poiteur sur method generique ?
    Ces methods auront toutes le meme prototype, le meme nom mais ne seront pas dans la meme class !

    Y'a t'il une possibilitee ?

    Merci d'avance pour votre reponse

    Bonne journee

  2. #2
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Est il possible de faire un poiteur sur method generique ?
    Ces methods auront toutes le meme prototype, le meme nom mais ne seront pas dans la meme class !
    Pas que je sache. Par contre, il y a peut-être une solution, à base de pattern nvi.

    Tu définis en virtuel une fonction _getFunction, qui renvoie un boost::any (ou un void*()). Ensuite, dans getFunction, tu le convertis avec un boost::any_cast (ou un cast C) en le type qui va bien.

    Comme de toute façon, GetProcAdress te renvoie un truc non-typé, tu n'échapperas au cast.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    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
     
    template<class DLLConcreteT>
    class DLHandler
    { 
    //...
    public:
        DLHandler(){}
     
        template <typename type>
        type getFunction(const std::string name)
        {
            return static_cast<DLLConcreteT*>(this)->do_get_function<type>(name);
        }
    //...
    }
     
    class MSDLLHandler : public DLHandler<MSDLLHandler>
    {
    public :
        template <typename type>
        type do_get_function(const std::string name)
        {
            // GetProcAddress ...
        }
    }
    F.A.Q. : CRTP

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 56
    Points : 44
    Points
    44
    Par défaut
    Bonjour,

    Merci pour vos reponses je viens pour cloturer le sujet et presenter la solution que j'ai adopte en esperant que cela aidera quelqu'un :p

    Je passe donc un poiteur sur la method de la fille que la mere doit appeller.
    En suite j'utilise un Hack via le typedef pour caster le "this" de la mere en un pointeur vers sa fille.

    Class Mere DLHandler (Abstraite)
    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
     
    typedef DLLLoader DLHANDLER;
     
    //...
    template <typename T>
    union table
    {
    	void*	_void;
    	T	_type;
    };
     
    std::map<std::string, void*>	_fct_buf;
    DLSYSFUNC	_get_fct;
    //...
     
    template <typename T>
    T call(const std::string name)
    {
    	table<T>	conv;
    		if (this->_fct_buf[name] == NULL)
    		this->_fct_buf[name] = (static_cast<DLHANDLER*>(this)->*_get_fct)(name);
    	conv._void = this->_fct_buf[name];
    	return (conv._type);
    }
    Class Fille DLLLoader
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    //...
    //dans le Constructeur : 
    this->_get_fct = &DLLLoader::getSysFunction;
    //...
     
    FARPROC DLLLoader::getSysFunction(const std::string name)
    {
    	return GetProcAddress(this->_lib_ptr, name.c_str());
    }
    Voila donc le DLHandler peut donc appeller sans modification du code soit la method du DLLLoader (Win) soit la methode SOLoader (unix/linux).

    La map est ici utilise pour bufferiser les poiteurs et eviter trop de recherches dans le DLL.

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

Discussions similaires

  1. Alternative au template de methode virtuelle pure
    Par lugarbleiz dans le forum Langage
    Réponses: 2
    Dernier message: 24/02/2010, 21h18
  2. Réponses: 2
    Dernier message: 20/10/2006, 15h07
  3. [debutant] probleme avec methode virtuelle pure
    Par Treuze dans le forum Débuter
    Réponses: 10
    Dernier message: 21/04/2006, 12h58
  4. Réponses: 19
    Dernier message: 10/02/2005, 22h43
  5. [Language] Méthodes virtuelle ?
    Par Eltaz dans le forum Langage
    Réponses: 2
    Dernier message: 12/01/2005, 21h43

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