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 :

Un pointeur de fonction membre utilisé comme pointeur de fonction


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 142
    Points : 89
    Points
    89
    Par défaut Un pointeur de fonction membre utilisé comme pointeur de fonction
    Bonjour à tous,

    Je suis en train de m'interfacer avec une lib écrite en C qui me demande un pointeur de fonction pour faire un callback.
    Mais moi, évidemment, j'aimerais que ma fonction de callback soit une fonction membre de mon objet.
    Pour feinter, j'ai procédé comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Recorder
    {
      public:
    		void Start();
    		int Process(int nframes, void * arg);
    		static int StaticProcess(int nframes, void * arg);
     
      private:
    		static Recorder * staticThis;
    };
    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
     
    void Recorder::Start()
    {
        staticThis = this;
        fonction_c_qui_demande_un_callback(client, &StaticProcess, 0);
    }
     
    int Recorder::Process(int, void * arg)
    {
    	//fait des choses avec les variables membres...
     
    	return 0;
    }
     
    int Recorder::StaticProcess(int nframes, void * arg)
    {
    	return staticThis->Process(nframes, arg);
    }
    C'est peut-être pas très élégant, mais ça fonctionne. [EDIT: N'importe quoi, ça fonctionnera plus dés que plusieurs objets seront créés… pfiou, vais prendre une pause, moi…]

    Ma question à ce sujet : n'existe-t-il pas une fonction de la librairie standard qui fasse quelque chose de ce genre ? J'ai cherché dans les mem_fun et co., mais rien n'a voulu compiler…

    Vous avez une idée ?

  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
    Si la fonction qui demande un callback ne permet pas de passer une donnée "utilisateur", c'est mort.

    Sinon:
    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
    typedef int (*CALLBACK_FUNC)(int, intptr_t);
     
    void FonctionQuiDemandeUnCallback(double blabla, CALLBACK_FUNC func, intptr_t user);
     
    class UneClasse
    {
    public:
    	static int SCallBack(int truc, intptr_t user);
    private:
    	int SCallBack(int truc);
    };
     
    int UneClasse::CallBack(int truc)
    {
    	...
    	return ...
    }
     
    int UneClasse::SCallBack(int truc, intptr_t user)
    {
    	return reinterpret_cast< UneClasse * >(user)->CallBack(truc);
    }
     
    int main(void)
    {
    	UneClasse cls;
    	FonctionQuiDemandeUnCallback(42.0, UneClasse::SCallBack, reinterpret_cast< intptr_t >(&cls));
    	return 0;
    }
    Je suis sûr que c'est quelque part dans la FAQ...
    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
    Profil pro
    Inscrit en
    Février 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 142
    Points : 89
    Points
    89
    Par défaut
    Ta remarque sur la donnée utilisateur m'a donné une idée.
    Il se trouve que le 0 de la fonction_c_qui_demande_un_callback (le 3ème argument) se récupère en tant que 2ème argument du callback (le void * arg).
    Du coup, la solution est vraiment toute bête !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Recorder
    {
      public:
    		void Start();
    		int Process(int nframes, void * arg);
    		static int StaticProcess(int nframes, void * arg);
    };
    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
     
    void Recorder::Start()
    {
        fonction_c_qui_demande_un_callback(client, &StaticProcess, this);
    }
     
    int Recorder::Process(int, void * arg)
    {
    	//fait des choses avec les variables membres...
     
    	return 0;
    }
     
    int Recorder::StaticProcess(int nframes, void * arg)
    {
    	return static_cast<Recorder*>(arg)->Process(nframes, arg);
    }
    Merci pour ton coup de main, Médinoc

  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
    C'est bien, sauf que normalement tu n'as pas besoin de mettre un second argument dans ta fonction Process non-statique.
    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
    Profil pro
    Inscrit en
    Février 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 142
    Points : 89
    Points
    89
    Par défaut
    En effet, plus besoin de lui…

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/12/2005, 12h33
  2. Réponses: 3
    Dernier message: 28/11/2005, 12h15
  3. Pointeur de fonction membre
    Par legend666 dans le forum C++
    Réponses: 1
    Dernier message: 04/10/2005, 20h46
  4. Réponses: 10
    Dernier message: 03/02/2005, 13h09
  5. Réponses: 5
    Dernier message: 12/01/2005, 20h58

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