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 :

pointeur de fonction et char*


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 4
    Par défaut pointeur de fonction et char*
    Bonjour,

    J'ai un petit soucis en C, je ne sait pas si c'est vraiment possible. Voila ce que je veux faire :
    Je veux faire un appel de fonction a partir d'un nom de fonction stocké en char *

    Un peu comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void (*onEnter)(void);
    char nom_de_fonction[7];
     
    strcpy ( nom_de_fonction, "doTest");
    onEnter = (void (*)(void))nom_de_fonction;
    Ce code ne fonctionne pas puisqu'il copie le pointeur du char * en le castant, plantage assuré. Donc voila ma question : Est ce que je veux faire est possible et comment ?

    Merci d'avance.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Malheureusement, tu ne peux pas faire ça directement justement parce que les noms de fonctions sont résolus en leur adresse mémoire respective à la compilation. Une fois l'exécutable produit, il n'en reste — a priori — aucune trace.

    Maintenant, ce que je dis n'est pas tout-à-fait vrai : les symboles des noms de fonctions sont officiellement exportés sauf lorsqu'ils sont déclarés static, mais il te faut encore parcourir l'exécutable de ton programme pour les retrouver.

    Par contre, tu peux créer une bibliothèque partagée (*.DLL sous Windows ou *.so sous Unix) qui contiennent ces fonctions et demander à charger cette bibliothèque pendant l'exécution grâce à des fonctions telles que dlopen(). À ce moment, tu retrouveras effectivement le point d'entrée de la fonction chargée grâce à son symbole et cela réalisera, en substance, ce que tu essaies de faire. Mais il s'agit là de programmation système, et pas de C standard. Par définition, ce n'est donc pas portable.

    À noter toutefois que les langages dotés de mécanismes d'introspection permettent de faire cela et, bien sûr, tous les langages de programmation interprétés peuvent le faire naturellement. La fonction consacrée s'appelle alors généralement « eval ».

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 4
    Par défaut
    En effet c'est bien une sorte d'eval() que je cherchais

    Bon tant pis, je me doutais un peu de la réponse mais qui ne tente rien n'a rien.

    Solution : au lieu de stocker le nom de la fonction, je vais stocker un indice qui pointera vers un tableau de pointeur de fonction.

    Merci pour ta réponse

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Citation Envoyé par s4m76 Voir le message
    Solution : au lieu de stocker le nom de la fonction, je vais stocker un indice qui pointera vers un tableau de pointeur de fonction.
    C'est effectivement la meilleure solution. Si, toutefois, tu veux quand même pouvoir appeler une fonction grâce à son nom, tu peux bâtir un tableau de structures, dont chacune contiendrait à la fonction une chaîne de caractère représentant le nom et un pointeur vers la fonction éponyme. De là, tu utilises une macro pour la remplir sans erreur et en une seule fois :

    Code C : 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
    #include <stdio.h>
    #include <string.h>
     
    #define FONC(X) { #X , X }
     
    void doTest (void)
    {
        printf ("Fonction de test invoquée.\n");
    }
     
    void MaPremiereFonction (void)
    {
        printf ("Première fonction invoquée.\n");
    }
     
    void MaSecondeFonction (void)
    {
        printf ("Seconde fonction invoquée.\n");
    }
     
    int main (int argc,char ** argv)
    {
        unsigned int i;
        struct {
            const char * nom;
            void (*ptr)(void);
        } tab [] =
        {
            FONC(doTest),
            FONC(MaPremiereFonction),
            FONC(MaSecondeFonction)
        };
     
        if (argc>1)
        for (i=0;i<(sizeof tab / sizeof *tab);++i)
        if (!strcmp(argv[1],tab[i].nom))
        (tab[i].ptr)();
     
        return 0;
    }

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ./programme doTest
    Fonction de test invoquée.
    $

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ./programme MaSecondeFonction
    Seconde fonction invoquée.
    $

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ ./programme NimporteQuoi
    $

    … par contre, ça t'oblige quand même à connaître la signature de tes fonctions à la base, et à leur imposer le même pour toutes.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 4
    Par défaut
    Je connaissais pas le #, c'est quoi ?

    En fait j'ai pas vraiment besoin du nom des fonctions, c'est pour un menu en embarqué. J'ai un .h qui contient les données du menu et pour chaque élément il est possible de spécifier une reference a une fonction a lancer.
    Donc un indice ira tres bien.

    Mais bon autre soucis, j'arrive pas a déclarer mon tableau correctement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void (*onEnterFunction)[](TreeMenu *) =
    {
            doUsine,
            doReset,
            editUint8Parameter,
            displayUint8Parameter,
            editFloatParameter,
            displayFloatParameter
    };
    me renvoie ca : "erreur: declaration of ‘onEnterFunction’ as array of functions"

    je compile avec avr-gcc

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 4
    Par défaut
    Bon en fait c'est bon, ca marche bien comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef void( *VOIDFUNC )(TreeMenu *);
     
    VOIDFUNC onEnterFunction[] =
    {
            doUsine,
            doReset,
            editUint8Parameter,
            displayUint8Parameter,
            editFloatParameter,
            displayFloatParameter
    };
    Merci pour le coup de main

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Citation Envoyé par s4m76 Voir le message
    Je connaissais pas le #, c'est quoi ?
    Le « # » seul, utilisé dans une définition de macro, permet de mettre un paramètre en guillemets, car si tu mets directement le nom du paramètre en guillemets toi même, il ne sera pas développé. Donc, dans l'exemple ci-dessus, ma macro

    … est développée en :

    .

    Mais bon autre soucis, j'arrive pas a déclarer mon tableau correctement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void (*onEnterFunction)[](TreeMenu *) =
    {
            doUsine,
            doReset,
            editUint8Parameter,
            displayUint8Parameter,
            editFloatParameter,
            displayFloatParameter
    };
    Le typedef est parfait. Sinon, il fallait juste mettre les crochets après le paramètre et non avant.

Discussions similaires

  1. opengl et pointeur de fonction
    Par Oldhar dans le forum C
    Réponses: 5
    Dernier message: 06/11/2003, 23h56
  2. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37
  3. Matrice de pointeurs de fonctions
    Par sebduth dans le forum C
    Réponses: 15
    Dernier message: 18/07/2003, 14h03
  4. [Kylix] Pointeur de fonctions
    Par _dack_ dans le forum EDI
    Réponses: 1
    Dernier message: 03/07/2003, 10h17
  5. pointeur de fonction
    Par kardath dans le forum C
    Réponses: 4
    Dernier message: 28/12/2002, 14h39

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