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 :

appel d'une fonction dont on ne connais le nom qu'au runtime


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Janvier 2005
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 31
    Points : 25
    Points
    25
    Par défaut appel d'une fonction dont on ne connais le nom qu'au runtime
    Bonjour à tous.
    J'ai une question :
    Imaginons qu'il existe une bibliothèque de fonctions qui est gérée par une personne A. Toutes les fonction ont le même prototype, mais des noms différents.
    La personne B ne connais pas le contenu précis de cette bibliothèque, mais il veut créer une méthode qui fait appel à une des fonctions de A sans connaitre son nom au moment où il écrit le code. La méthode de la personne B va lire un nom dans un fichier texte par exemple, et appel la fonction de A qui a ce nom.

    Comment réalise-t-on ce type de mécanisme, où on veut appeller une fonction dont on ne connaitra le nom qu'au moment de l'éxécution et non au moment de la compilation ?

    Merci de toute aide / lien / info.

  2. #2
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Il va falloir passer par un mécanisme de "factory". En gros, il faut pré enregistrer tes fonctions...
    Exemple (non testé, non compilé).
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    class CFunctionFactory : private boost::noncopyable
    {
    public:
            typedef boost::function<void()> my_function; // Ton prototype
    	/**
            * \brief Get static instance of factory.
            */
    	static CFunctionFactory & Instance()
    	{
    		static CFunctionFactory  instance;
    		return instance;
    	}
     
    	/**
            * \brief Register a function
            */
    	void RegisterFunction(const std::string& str, boost::function<my_function func)
    	{
    		m_map[str] = func;
    	}
     
    	/**
            * \brief Get the function
            */
    	my_function GetFunction(const std::string& str)
    	{
    		return m_map[str];
    	}
     
    private:
    	CFunctionFactory () {}
    	std::map<std::string, my_function > m_map;
    };
     
    void coucou()
    {
       std::cout << "coucou" << std::endl;
    }
     
    void hello()
    {
       std::cout << "hello" << std::endl;
    }
     
    int main()
    {
         CFunctionFactory::Instance().RegisterFunction("coucou", &coucou);
         CFunctionFactory::Instance().RegisterFunction("hello", &hello);
     
         CFunctionFactory::Instance().GetFunction("coucou")();
         CFunctionFactory::Instance().GetFunction("hello")();
    }

  3. #3
    Membre habitué Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Points : 190
    Points
    190
    Par défaut
    Excusez moi, je me greffe sur ce thread pour poser une petite question qui m'est venue en lisant :
    poukill dans ton exemple de code tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef boost::function<void()> my_function;
    --> c'est quoi le type "void()" que tu passes au template ?
    Ça a l'air d'être le type d'une fonction sans arguement ni retour, mais dans ce cas, est-ce que ça ne devrait pas être "void(*)()" ?
    Si ça n'est pas ça, qu'est ce que c'est ?
    [WinXP sp3 / Visual 2005 / Eclipse Ganymede / Python 2.6]
    Hadrien

  4. #4
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par sopsag Voir le message
    c'est quoi le type "void()" que tu passes au template ?
    Si si, c'est bien le prototype de la fonction...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef boost::function<int(double)> my_function;
    prend un double et retourne un int !

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    188
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 188
    Points : 248
    Points
    248
    Par défaut
    void(*f)() est un pointeur sur une fonction qui ne prend ni ne renvois d'argument mais, si je me souvient bien, void f() est équivalent. En effet les fonction ne sont pas des donnée que tu peux modifier, incrémenter, ect... le compilateur considère donc que c'est la même chose.

    voir la faq

  6. #6
    Membre habitué Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Points : 190
    Points
    190
    Par défaut
    Je me suis amusé à écrire ce truc là :
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    double titi ( double x ) { return x*x ;}
    double tata ( double x ) { return x+1 ;}
    double toto ( double x ) { return 1-x ;}
     
    // pool de pointeurs de fonctions : <func> doit être un pointeur de fonction
    template <class func> class FunctionPtrPool
        {
        public:
            FunctionPtrPool ()            { _nb = 0 ;}
            func operator[] ( int index ) { return( _table[index] ) ;}
            void operator += ( func f )   { _table[_nb++] = f ;}
        private:
            int  _nb ;
            func _table [5] ;
        } ;
     
    // pool de fonctions : <func> doit être une fonction
    // NB : cette classe est une copie de la précédante avec une '*' à tous les 'func'.
    template <class func> class FunctionPool
        {
        public:
            FunctionPool ()                 { _nb = 0 ;}
            func * operator[] ( int index ) { return( * _table[index] ) ;}
            void   operator += ( func * f ) { _table[_nb++] = f ;}
        private:
            int    _nb ;
            func * _table [5] ;
        } ;
     
    // on test tout ça...
    void test_template_func_typed ()
        {
        FunctionPtrPool<double(*)(double)> f_double ;
        f_double += titi ;
        f_double += tata ;
        f_double += toto ;
     
        FunctionPool<double(double)> f_double_ptr ;
        f_double_ptr += tata ;
        f_double_ptr += toto ;
        f_double_ptr += titi ;
     
        double(*f)(double) = titi ;
     
        cout << f_double[0]( 3 ) + f_double_ptr[1]( 3 ) + f( 5 ) ;
        }
    et je constate que double(double) est le type de la fonction elle même alors que double(*)(double) est le type du pointeur de fonction. Je n'avais jamais rencontré l'écriture double(double)...
    Voilà, je me coucherai moins bête !
    [WinXP sp3 / Visual 2005 / Eclipse Ganymede / Python 2.6]
    Hadrien

Discussions similaires

  1. appeler une fonction dont le nom est dans un parametre
    Par djams9 dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 15/06/2011, 11h42
  2. Appeler une fonction dont le nom dépend d'une variable
    Par Cthulhu 22 dans le forum Langage
    Réponses: 7
    Dernier message: 14/08/2007, 16h01
  3. Réponses: 4
    Dernier message: 02/06/2004, 16h35
  4. Appel d'une fonction
    Par jfphan dans le forum ASP
    Réponses: 4
    Dernier message: 14/04/2004, 15h06
  5. A la recherche de l'appel d'une fonction...
    Par karl3i dans le forum C
    Réponses: 3
    Dernier message: 24/09/2003, 12h34

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