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 :

pointeur sur fonction


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut pointeur sur fonction
    Bonjour à toutes et à tous,

    Dans une application "Arduino", j'utilise une bibliothèque que j'ai créée (un bon millier de lignes) dont la partie congrue révélant le problème est la suivante :

    fichier "BaseComp.h" :

    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
    #ifndef BaseComp_h
    #define BaseComp_h
     
    #include <Arduino.h>
     
    class CompBase {
    public:
    	CompBase() { // constructeur
    		surAppui = NULL;
    	}
    	void (* surAppui)(); // pointeur sur une fonction d'action en cas d'appui sur le composant
    	virtual void select();
    };
     
    #endif

    le fichier "BaseComp.cpp" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <Arduino.h>
    #include <BaseComp.h>
     
    void CompBase::select() { // fonction virtuelle
    	if (surAppui != NULL)
    		surAppui();
    }
    Dans l'appli :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ...
     
    void maProcedure() {
      ...}
     
    CompBase monComposant;
    ...
      monComposant.surAppui = &maProcedure
    Qu'est-ce que "BaseComp ? C'est l'équivalent d'une bibliothèque de composants visuels qui répondent à des évènements. Dans mon cas, c'est un appui sur l'écran tactile qui est détecté via la méthode "select()" et qui, si un méthode a été attachée à la variable "surAppui", va effectuer ce que doit faire cette méthode (ici, le méthode "maProcedure()")


    Le problème semble venir de l'affectation de la méthode "maProcedure" à la variable "surAppui" de l'instance "monComposant" de la classe "CompBase".

    Pour en revenir au problème, si je n'affecte pas de méthode à la variable "surAppui", le problème disparait ... comme tout l'intérêt de ma construction.

    Pour autant je subodore que le problème tourne autour de cette affectation. Vous semble t-elle correcte ? quel pourrait être le "bug" dans tout ça ?

    Je vous remercie d'avoir déjà pris la peine de lire tout cela et vous remercierai encore de votre aide.

    Cordialement.

    Pierre

  2. #2
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    Salut, quel est le problème rencontré? L'appel ne fonctionne pas? segfault?

    L'assignation me semble correct, ensuite tout dépends du problème que tu rencontre .
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    salut,

    ça s'apelle un pointeur sur fonction, avec ce terme tu retrouveras de très nombreux posts sur ce forum-même à ce sujet.

    Je suppose que ça crash au moment d'appeler la fonction pointée ?
    Puisque la syntaxe, si j'ai bonne mémoire, devrait être (*surAppui)();
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par skeud Voir le message
    Salut, quel est le problème rencontré? L'appel ne fonctionne pas? segfault?

    L'assignation me semble correct, ensuite tout dépends du problème que tu rencontre .
    Je l'ai reporté ici car ce me semble être un problème de pure syntaxe du C++.

    Citation Envoyé par Bousk Voir le message
    ... Je suppose que ça crash au moment d'appeler la fonction pointée ?
    Puisque la syntaxe, si j'ai bonne mémoire, devrait être (*surAppui)();
    Non, ça ne crash pas à l'appel de la fonction, voir le lien donné dans la réponse précédente. Le problème rencontré me semble complètement farfelu !!! Comme si la compilation de ce lien de fonction allait écrire dans des registres dans lequel le programme se perd.

    La syntaxe que tu proposes fonctionne comme celle que j'ai emplyée et le problème reste le même.

    Cordialement.

    Pierre

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Merci de poster le problème complet ici, nous ne devrions pas avoir à aller sur un lien externe à DVP. Surtout pour un "problème" aussi simple.

    Si le problème est
    PbConst.cpp.o: In function `majJours()':
    /Arduino/PbConst.ino:10: undefined reference to `nbZones'
    collect2: error: ld returned 1 exit status
    Alors il suffit de lire l'erreur pour la comprendre...
    Ton linker ne trouve pas ta variable déclarée extern et jamais déclarée réellement dans ton programme.
    La syntaxe de foncteur est correcte, ce n'est pas du tout le problème ici.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Merci de poster le problème complet ici, nous ne devrions pas avoir à aller sur un lien externe à DVP. Surtout pour un "problème" aussi simple. ...
    Désolé, vous le trouverez ci-après

    Citation Envoyé par Bousk Voir le message
    ... Si le problème est

    PbConst.cpp.o: In function `majJours()':
    /Arduino/PbConst.ino:10: undefined reference to `nbZones'
    collect2: error: ld returned 1 exit status


    Alors il suffit de lire l'erreur pour la comprendre...
    Ton linker ne trouve pas ta variable déclarée extern et jamais déclarée réellement dans ton programme.
    La syntaxe de foncteur est correcte, ce n'est pas du tout le problème ici.
    Effectivement, l'erreur dit bien ce que ça veut dire ... à ceci près, et je l'ai dit dans mon explication, que si je ne lie pas la méthode majCours à la variable surAppui, ou que je n'appelle pas la méthode majZN_CY, et bien ça compile sans problème. Ma déclaration extern est donc correcte. Il semble donc que ce soit l'une des deux actions citées qui viennent provoquer le problème. C'est peut-être un problème du compilateur Arduino. Je voudrais m'assurer que ce n'est pas dû à un mauvais codage de ma part.

    Cordialement.

    Pierre

    L'application suivante est destinée à des modules "Arduino"

    Dans une application constituée d'un fichier "PbConst.ino" et d'un fichier "LesPages.cpp" je souhaite pouvoir utiliser la constante "NbZones" dans chacun des deux fichiers. Pour cela, je la crée dans le fichier "LesPages.cpp" et la déclare comme "extern" dans le fichier "PbConst.ino". Cette construction fonctionne normalement. Si dans le fichier "PbConst.ino".vous mettez en commentaire soit la ligne : majZn_Cy(zN); ou la ligne : leBouton.surAppui = &majJours; alors, ça compile, sinon, j’obtiens l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PbConst.cpp.o: In function `majJours()':
    /Arduino/PbConst.ino:10: undefined reference to `nbZones'
    collect2: error: ld returned 1 exit status

    le fichier "PbConst.ino :

    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
    #include <BaseComp.h>
     
    extern byte nbZones;
    extern void majZn_Cy(byte);
     
    CompBase leBouton;
     
    void majJours() {
      byte zN;
      for (byte i = 0; i < nbZones; i++)
          zN = i;
      majZn_Cy(zN);
    }
     
    void setup() {
      leBouton.surAppui = &majJours;
    }
     
    void loop() {
    }

    le fichier "LesPages.cpp" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <Arduino.h>
     
    const byte nbZones = 6; // Nombre de zones
     
    void majZn_Cy(byte Z) {
    }

    Le problème semble venir de l'affectation de la méthode "majJours" à la variable "surAppui" de l'instance "leBouton" de la classe "CompBase".

    "CompBase" est déclaré dans une bibliothèque que j'ai créée : "BaseComp.h" et BaseComp.cpp" qui, au complet représentent un bon millier de lignes. J'ai réussi à en extraire la partie congrue (quelques lignes seulement) qui occasionne le problème. La voici :

    fichier "BaseComp.h" :
    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
     
    #ifndef BaseComp_h
    #define BaseComp_h
     
    #include <Arduino.h>
     
    class CompBase {
    public:
    	CompBase() { // constructeur
    		surAppui = NULL;
    	}
    	void (* surAppui)(); // pointeur sur une fonction d'action en cas d'appui sur le composant
    	virtual void select();
    };
     
    #endif

    le fichier "BaseComp.cpp" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <Arduino.h>
    #include <BaseComp.h>
     
    void CompBase::select() { // fonction virtuelle
    	if (surAppui != NULL)
    		surAppui();
    }

    Qu'est-ce que "BaseComp ? C'est l'équivalent d'une bibliothèque de composants visuels qui répondent à des évènements. Dans mon cas, c'est un appui sur l'écran tactile qui est détecté via la méthode "select()" et qui, si un méthode a été attachée à la variable "surAppui", va effectuer ce que doit faire cette méthode (ici, le méthode "majJours()")

    Pour en revenir au problème, si je n'affecte pas de méthode à la variable "surAppui", le problème disparait ... comme tout l'intérêt de ma construction.

    A savoir : si je n'utilise pas la constante "nbZones" dans le fichier "PbComp.ino", tout fonctionne correctement.

    Pour autant je subodore que le problème tourne autour de cette affectation. Vous semble t-elle correcte ? quel pourrait être le "bug" dans tout ça ?

    Je vous remercie d'avoir déjà pris la peine de lire tout cela et vous remercierai encore de votre aide.

    Cordialement.

    Pierre

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Compiles-tu le fichier LesPages.cpp et comment est-il linké?


    PS: tu as loupé l'insertion de ton code: le fichier PbConst.ino: il est en 3 morceaux plus l'introduction dedans

  8. #8
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par foetus Voir le message
    ... PS: tu as loupé l'insertion de ton code: le fichier PbConst.ino: il est en 3 morceaux plus l'introduction dedans
    Je me suis mélangé les crayons en faisant la copie ; c'est réparé.

    Citation Envoyé par foetus Voir le message
    Compiles-tu le fichier LesPages.cpp et comment est-il linké? ...
    Les deux fichiers "PbConst.ino" et "LesPages.cpp" sont dans un même répertoire et pris en charge pas le compilateur Arduino. Je ne saurais en dire plus la-dessus. Mais je le répète, tout fonctionne bien si il n'y a pas le lien avec surAppui ou pas d'appel à la méthode majZN_CY. Le compilateur prend donc normalement en compte ces deux fichiers.

    Cordialement.

    Pierre

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par ChPr Voir le message
    Mais je le répète, tout fonctionne bien si il n'y a pas le lien avec surAppui ou pas d'appel à la méthode majZN_CY. Le compilateur prend donc normalement en compte ces deux fichiers.
    Et je répète que la syntaxe du foncteur est correcte. Y'a rien de surprenant que si tu utilises pas la fonction l'erreur "disparaisse", le compilateur peut faire des optimisations, et supprimer le code inutile en fait partie.
    Il n'en reste pas moins, je le répète, que le problème est cette variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    extern byte nbZones;
    const byte nbZones = 6;
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Et je répète que la syntaxe du foncteur est correcte. Y'a rien de surprenant que si tu utilises pas la fonction l'erreur "disparaisse", le compilateur peut faire des optimisations, et supprimer le code inutile en fait partie.
    Il n'en reste pas moins, je le répète, que le problème est cette variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    extern byte nbZones;
    const byte nbZones = 6;
    Je dois être vraiment bouché

    Si tu dis que le problème est cette variable, alors c'est quoi le problème ?

    Que dois-je écrire pour que le problème disparaisse ?

    Cordialement.

    Pierre

  11. #11
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    L'erreur est pourtant explicite:
    cannot find symbol = il ne trouve pas la source de ta variable, autrement dis tu ne compile pas la source contenant la variable.
    Le externe n'est la que pour signifier de ne pas recompiler l'instanciation de la variable mais pour faire comprendre au compilo qu'une variable portant ce nom est instancier dans un autre fichier.
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  12. #12
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par skeud Voir le message
    L'erreur est pourtant explicite:
    cannot find symbol = il ne trouve pas la source de ta variable, autrement dis tu ne compile pas la source contenant la variable. ...
    Soit, mais alors, pourquoi la trouve-t-il si je ne mets pas les lignes qui provoquent le problème ? Pour cette variable, je ne fais rien de plus, rien de moins dans ce cas ... et ça compile !

    Pour moi, ces deux lignes à problème n'ont strictement rien à voir avec cette variable et pourtant, il y a interaction. C'est ce que je n'arrive pas à comprendre.

    Formulé autrement : OK, le compilateur ne voit pas cette variable. Mais alors, pourquoi la voit-il dans un cas et pas dans l'autre alors que je n'ai rien modifié en ce qui concerne cette variable ?

    C'est peut-être clair pour vous, mais pas pour moi.

    Cordialement.

    Pierre

  13. #13
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par ChPr Voir le message
    pourquoi la voit-il dans un cas et pas dans l'autre alors que je n'ai rien modifié en ce qui concerne cette variable ?
    Citation Envoyé par Bousk Voir le message
    le compilateur peut faire des optimisations, et supprimer le code inutile en fait partie.
    une fonction non utilisée, c'est la définition de code inutile..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  14. #14
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Citation Envoyé par Bousk Voir le message
    une fonction non utilisée, c'est la définition de code inutile..
    Ben oui, ça supprime le code de la fonction non utilisée, mais je ne vois pas pourquoi ça supprimerait celui attaché à la variable à laquelle je n'ai pas touché.

    J'ai transféré cette variable dans une bibliothèque et tout fonctionne, comme il se doit, normalement.

    Merci pour vos suggestions.

    Cordialement.

    Pierre

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 03/02/2005, 13h09
  2. Réponses: 5
    Dernier message: 12/01/2005, 20h58
  3. pointeurs sur fonction en C++
    Par cemoi dans le forum C++
    Réponses: 7
    Dernier message: 29/11/2004, 13h19
  4. [langage] Pointeur sur fonction
    Par Fanch.g dans le forum Langage
    Réponses: 2
    Dernier message: 02/10/2004, 10h43
  5. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37

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