Appel d'une fonction via un string

Résolu
Tom59247 Messages postés 27 Date d'inscription jeudi 7 janvier 2010 Statut Membre Dernière intervention 7 février 2013 - 21 août 2012 à 16:33
Tom59247 Messages postés 27 Date d'inscription jeudi 7 janvier 2010 Statut Membre Dernière intervention 7 février 2013 - 22 août 2012 à 11:59
Bonjour, je cherche à appeler une fonction grâce à un string. le mieux étant de vous faire un exemple,

void function1{
cout << "fonction 1";
}
void function2{
cout << "fonction 2";
}

int main()
{
string LeNomDeMaFonction = "function1";
LeNoDeMaFonction();
return 0;
}


j'ai la possibilité d'utiliser un simple strcmp mais je vais devoir réaliser ceci pour un grand nombre de fonction donc énormément de condition :/

Une idée ? un coup de pouce ?

Merci d'avance pour vos réponses !

4 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
21 août 2012 à 17:08
Bonjour.

Tout d'abord:
- Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
- Seul les noms de classe devraient porter une majuscule, pas les fonctions.

Pour répondre à ta question: Tu vas être obligé de faire des "else if" avec des "==" partout (pas besoin de strcmp).
Le mieux étant tout de même d'avoir des enums plutôt que des std::string...

Voici deux techniques:
#include 

void function1()
{
  std::cout << "fonction 1" << std::endl;
}

void function2()
{
  std::cout << "fonction 2" << std::endl;
}

int main()
{
  std::string name = "function1";

  if (name == "function1")
    function1();
  else if (name == "function2")
    function2();

  return 0;
}


OU

#include 

void function1()
{
  std::cout << "fonction 1" << std::endl;
}

void function2()
{
  std::cout << "fonction 2" << std::endl;
}

typedef void (*func)();
struct Func
{
  std::string name_;
  func pFunc_;
};


static const Func tabFunc[] =
  {
    {"function1", function1},
    {"function2", function2}
    // etc...
  };

int main()
{
  std::string name = "function1";

  const int size = sizeof (tabFunc) / sizeof (*tabFunc);
  for (int i = 0; i < size; ++i)
    if (tabFunc[i].name_ == name)
      (*tabFunc[i].pFunc_)(); // On peut ajouter un "break" si le nom de méthode est unique

  return 0;
}


Voir même en mettant une macro:
#include 

void function1()
{
  std::cout << "fonction 1" << std::endl;
}

void function2()
{
  std::cout << "fonction 2" << std::endl;
}

typedef void (*func)();
struct Func
{
  std::string name_;
  func pFunc_;
};

#define DECLARE(X) {#X, X}

static const Func tabFunc[] =
  {
    DECLARE(function1),
    DECLARE(function2)
    // etc...
  };

int main()
{
  std::string name = "function1";

  const int size = sizeof (tabFunc) / sizeof (*tabFunc);
  for (int i = 0; i < size; ++i)
    if (tabFunc[i].name_ == name)
      (*tabFunc[i].pFunc_)(); // On peut ajouter un "break" si le nom de méthode est unique

  return 0;
}


Si tu pouvais expliquer la finalité de ta démarche, peut être pourrait-on te conseiller une approche plus efficace.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
21 août 2012 à 17:33
Dans ce cas, il te faut faire la méthode suivante:
- On considère que le nom des fonctions est unique.
- Tu mets tes fonctions dans un tableau (méthode 2, de mon précédent mail) *trié* par nom.
- Tu sors de la boucle si le nom à chercher est > à celui de l'élément du tableau en cours (ce qui veut dire que tu ne l'as pas trouvé).
- Si tu trouves un élément qui correspond, tu lances la fonction, suivit d'un "break" pour éviter de continuer à chercher.

C'est ce qu'il y a de plus rapide, après peut être une recherche dichotomique (qui ne sera nécessaire que si vraiment tu as beaucoup de fonction).
Enfin, si le nombre de fonction est réellement grand, ou si la notion de performance est primordiale, alors il te faudra utiliser un hash_map (std::map ou std::unordered_map).

Plusieurs optimisations plus ou moins facile à coder sont possibles, en fonction des performances attendues et du nombre de fonction à analyser.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
3
Tom59247 Messages postés 27 Date d'inscription jeudi 7 janvier 2010 Statut Membre Dernière intervention 7 février 2013
21 août 2012 à 17:24
Merci pour la réponse précise et rapide :)

pour expliquer rapidement,

je dois réalise un hook sur presque l'intégralité des message windows, et rebondir sur certain messages jusqu’à maintenant ca avance plutôt bien mais nouvelle demande, réaliser un fichier de conf ayant ce format : Windows_Message_a_hook/Fonction_a_lancer

je souhaitais juste lancer directement le nom de variable recup dans le fichier de conf +() mais c’était trop facile :D

Je test ta méthode demain et je reviens accepté la réponse dès que ca tourne :)

Merci encore, Bonne soirée
0
Tom59247 Messages postés 27 Date d'inscription jeudi 7 janvier 2010 Statut Membre Dernière intervention 7 février 2013
22 août 2012 à 11:59
Voilà testé et approuvé.

La performances n'est pour l'instant pas un objectif primaire, donc ca sera parfait :D

Merci pour le coup de main :)
0
Rejoignez-nous