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 :

Nom de fonction "dynamique"


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut Nom de fonction "dynamique"
    Bonjour,

    Dans le cadre de mon travail, je souhaite faire une operation un peu acrobatique :
    A partir d'un nom de fonction contenu dans un char j'aimerais appeler une fonction dont le nom correspond a ladite fonction.
    Ex:
    Dans le fichier mesFonctions.c, je definis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int fonction1 (char toto)
    { 
    //blablabla;
    }
    int fonction2 (char toto)
    { 
    //blobloblo;
    }
    et dans le fichier main.c, je recupere dans une base de donnee le nom de la fonction1 dans un char:
    fname = "function1";

    Ce que je voudrais savoir c'est s'il y a un moyen de passer direct de fname a l'appel de la fonction1 sans passer par un tableau de pointeur de fonctions genere en amont (a partir de mesFonctions.c par ex) et que je parcourrais pour retrouver le pointeur adequat (comme j'ai vu dans tous les exemples d'utilisation de pointeurs de fonction trouves sur le net) i.e faire un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int (*pfunction) (char); 
    pfunction = &((int(*) (char))*fname);
    ???)

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Il faut utiliser un tableau de pointeurs, ou quelque chose d'équivalent. C'est la seule solution portable. Sinon, exploiter la connaissance du format des exécutables mais là tout dépend du système d'exploitation. Sous Windows, on pourra se baser sur l'utilisation de la fonction GetProcAddress. Il y a sûrement un équivalent de cette fonction chez les autres systèmes mais je ne les connais pas.

  3. #3
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Sur les systèmes POSIX tu peux utiliser dlopen() et dlsym() pour charger puis appeler une fonction par son nom. Mais il faut que la fonction soit définie (et exportée) dans un shared object.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 402
    Points : 23 785
    Points
    23 785
    Par défaut
    Pour compléter ce que disent Melem et matafan, ce genre de chose est possible (et courant) avec les langages interprétés (généralement à l'aide de « eval ») et les langages permettant l'introspection.

    La raison pour laquelle tu es obligé, en C, de passer par un tableau de pointeur est que la compilation se fait avant l'exécution et qu'ensuite, à ce stade, tous les symboles sont résolus en leur adresse en mémoire. Les symboles qui n'ont pas vocation à être exportés disparaissent donc purement et simplement.

    Toutefois, les fonctions qui ne sont pas déclarées static sont exportées et apparaissent donc dans l'exécutable, mais c'est à l'intention du linker, pas du programme lui-même.

    Donc, en gros, soit tu déclares effectivement un tableau de pointeurs associés à leur nom en toutes lettres, en t'aidant éventuellement d'une macro, et c'est portable, soit tu utilises ce que le compilateur a exporté pour toi, mais c'est dépendant du système d'exploitation et du format d'exécutable que tu utilises.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Ok, je comprends bien.
    Je vous remercie en tout cas. Je vais voir ce que je peux faire mais je vais probablement utiliser un tableau de pointeur sur fonction. C'est dommage mais bon au moins ca devrait marcher.
    Merci encore !

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 402
    Points : 23 785
    Points
    23 785
    Par défaut
    Citation Envoyé par chouetz Voir le message
    je vais probablement utiliser un tableau de pointeur sur fonction. C'est dommage mais bon au moins ca devrait marcher.
    Oui, c'est « dommage » mais au fond, une fois compilé, ça revient exactement au même dans l'exécutable et ça te permet d'utiliser également les fonctions statiques.

    Comme suggéré plus haut, je te conseille d'utiliser une macro #define à laquelle tu ne passes qu'une seule fois le nom de la fonction et qui te génère automatiquement le pointeur et la chaîne de caractère associée. Ça évite de faire deux fois le même travail et tu es sûr d'éliminer toute faute de correspondance.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    ca revient pas trop au meme parce que dans ma fonction, je suis dans une triple boucle sur des listes chainees de structures imbriquees (sic), et a cet endroit precis, j'ai une liste d'element sur lequel je dois operer une fonction specifique en fonction de l'element (l'element est une structure qui contient le nom de sa fonction associee).

    Ce nom je le recupere en DB sous forme de string. Du coup si plus ou moins a la volee j'avais pu faire un lien direct entre le nom de la fonction et la fonction elle meme pour l'appeler c'aurait ete cool.

    Du coup la il va falloir que je construise d'une part mon tableau avec pointeurs, la ou je declare toutes les fonctions, et d'autre part que j'y fasse appel au fin fond de ma boucle.
    Heureusement au moment ou je construis mon tableau je peux l'ordonner dans le meme ordre de traitement de mes elements donc j'aurais pas de boucle supplementaire a faire pour faire le lien, mais je trouve que c'est moins "esthetique"

    Je sais pas si c'est tres clair :p

  8. #8
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    et pourquoi pas un switch ???

  9. #9
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    et pourquoi pas un switch ???
    Tu voulais certainement dire une série de if ... else car switch n'est pas d'une très grande utilité quand on manipule des chaînes, mais c'est toujours de la catégorie de la solution tableau (ou liste alors si tu préfères) de pointeurs de fonction.

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    Tu voulais certainement dire une série de if ... else car switch n'est pas d'une très grande utilité quand on manipule des chaînes, mais c'est toujours de la catégorie de la solution tableau (ou liste alors si tu préfères) de pointeurs de fonction.
    non, je parlais bien d'un switch, éventuellement suivi de ifs...

    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
    switch ( Operation[0] )
      {
         case 'A' :    /* Addition */
             ....
             break ;
     
         case 'M' : /* Multplication */
             ...
             break ;
     
         case 'L' :  /* Log */
               switch ( Operation[1] )   /* ou if */
                  {
                     case 'N' : /* log népérien */
                         ...
                         break ;
     
                     case 'D' :  /* Log décimal */
                     default :
                          ...
                          break ;
                   }
                break ;
          ...
    }


    De toutes façons il faudra lister quelque part les adresses, soit dans un tableau soit là directement...

    Un if..else implique plus d'opérations, puisqu'il faut tester à chaque fois.. et donc les derniers peuvent nécessiter beaucoup de tests.

    Sinon une autre solution élégante consiste à faire un tableau à 2 dimensions, avec une chaîne et une adresse, et reconnaitre le nom dans le tableau et par l'indice de boucle appeler la fonction par son adresse...

Discussions similaires

  1. Nom de fonction dynamique
    Par gege2061 dans le forum C
    Réponses: 2
    Dernier message: 21/06/2005, 14h44
  2. [xsl]simuler le mecanisme OO de "liaison dynamique"
    Par philemon_siclone dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 19/12/2003, 11h34

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