OVH Cloud OVH Cloud

appeler dynamiquement une fonction

31 réponses
Avatar
Nicolas aunai
salut,

j'aimerai avoir un stratagème pour appeler dynamiquement une fonction...

j'ai pensé a mettre dans un tableau, des pointeurs pointant vers les
fonctions que je veux appeler, mais je ne voit pas comment executer une
fonction en manipulant un pointeur sur elle....


--
nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@nospam@hotmail.com

10 réponses

1 2 3 4
Avatar
Laurent
Il y a des exemples ici :
http://www.function-pointer.org/CCPP/FPT/em_fpt.html
Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Nicolas aunai" @free.fr> wrote:

j'aimerai avoir un stratagème pour appeler dynamiquement une fonction...


Pointeur de fonction.

j'ai pensé a mettre dans un tableau, des pointeurs pointant vers les
fonctions que je veux appeler, mais je ne voit pas comment executer une
fonction en manipulant un pointeur sur elle....


typedef int puts_f (char const *s);

#include <stdio.h>

int main (void)
{
puts_f *pf = puts;

pf ("hello world");

return 0;
}

Ou, si tu aimes le gore:

#include <stdio.h>

int main (void)
{
int (*pf) (char const *s) = puts;

pf ("hello world");

return 0;
}

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Nicolas aunai
Emmanuel Delahaye a écrit:

j'ai pensé a mettre dans un tableau, des pointeurs pointant vers les
fonctions que je veux appeler, mais je ne voit pas comment executer
une fonction en manipulant un pointeur sur elle....


typedef int puts_f (char const *s);

#include <stdio.h>

int main (void)
{
puts_f *pf = puts;

pf ("hello world");

return 0;
}


euh ouais ok ça j'ai pigé, mais.... imaginons un instant que je fasse une
application client/serveur, le client est chargé de donner l'ordre au
serveur d'executer une fonction parmis toute une collection. en quoi le
pointeur de fonction peut m'être utile ?

je veux dire, si j'ai dans chque case d'un tableau (du serveur) un pointeur
sur une de mes fonctions, est-ce possible que le client déclenche la
fonction en accédant a la case de son pointeur dans ce tableau ? :/

je dirais....

si j'ai un tableau :

puts_f *tab[2]; en supposant que ça se déclare comme ça...

ça veut dire que les deux éléments de ce tableau sont obligatoirement des
pointeurs vers des fonctions de type puts_f, comment je fais si chaque
fonction est différente ? un tableau de structure donc le membre est un
pointeur de fonction ? :'(

secondo, pour appeler la fonction et lui passer ses arguments je fais
comment ? comme ça : (?)

*tab[0](arg1,arg2,arg3); ???


Ou, si tu aimes le gore:


.... non :)


Avatar
Bertrand Mollinier Toublet
Nicolas aunai wrote:
Emmanuel Delahaye a écrit:


j'ai pensé a mettre dans un tableau, des pointeurs pointant vers les
fonctions que je veux appeler, mais je ne voit pas comment executer
une fonction en manipulant un pointeur sur elle....


typedef int puts_f (char const *s);

#include <stdio.h>

int main (void)
{
puts_f *pf = puts;

pf ("hello world");

return 0;
}



euh ouais ok ça j'ai pigé, mais.... imaginons un instant que je fasse une
application client/serveur, le client est chargé de donner l'ordre au
serveur d'executer une fonction parmis toute une collection. en quoi le
pointeur de fonction peut m'être utile ?

je veux dire, si j'ai dans chque case d'un tableau (du serveur) un pointeur
sur une de mes fonctions, est-ce possible que le client déclenche la
fonction en accédant a la case de son pointeur dans ce tableau ? :/

je dirais....

si j'ai un tableau :

puts_f *tab[2]; en supposant que ça se déclare comme ça...

ça veut dire que les deux éléments de ce tableau sont obligatoirement des
pointeurs vers des fonctions de type puts_f, comment je fais si chaque
fonction est différente ? un tableau de structure donc le membre est un
pointeur de fonction ? :'(

secondo, pour appeler la fonction et lui passer ses arguments je fais
comment ? comme ça : (?)

*tab[0](arg1,arg2,arg3); ???

Dans les grandes lignes, oui.


Mais...

Les pointeurs sur des fonctions de signature differente sont
*incompatibles*. Tu ne peux donc pas ranger dans le meme tableau un
pointeur sur une fonction prenant un int en argument et un pointeur sur
une fonction prenant un double (par exemple). Ca limite considerablement
l'interet et le domaine d'application du truc.

Un compromis possible est que toutes les fonctions que tu utilises aient
le meme type de retour, auquel cas tu peux utiliser un tableau de
pointeur sur des fonctions aux arguments non specifies et retournant le
type commun:

typedef int (*hook)();

int hook1();
int hook2();

hook hook_table[2] = { hook1, hook2 };

int main(void)
{
return 0;
}

int hook1(int a)
{
/* ... */
}

int hook2(char *b, double c)
{
/* ... */
}

C'est un compromis dans la mesure ou tu perds la verification du type
des arguments par le compilateur (puisque tes fonctions sont declarees
comme prenant un ensemble non specifie d'arguments).

--
Bertrand Mollinier Toublet
Currently looking for employment in the San Francisco Bay Area
http://bmt-online.dapleasurelounge.com/



Avatar
Nicolas aunai
Bertrand Mollinier Toublet a écrit:

Dans les grandes lignes, oui.

Mais...

Les pointeurs sur des fonctions de signature differente sont
*incompatibles*. Tu ne peux donc pas ranger dans le meme tableau un
pointeur sur une fonction prenant un int en argument et un pointeur
sur
une fonction prenant un double (par exemple). Ca limite
considerablement l'interet et le domaine d'application du truc.


c'est exactement sur celà que je me prend la tête depuis que j'ai tapé mon
précédent post !! :'(


Un compromis possible est que toutes les fonctions que tu utilises
aient
le meme type de retour, auquel cas tu peux utiliser un tableau de
pointeur sur des fonctions aux arguments non specifies et retournant
le
type commun:

typedef int (*hook)();

int hook1();
int hook2();

hook hook_table[2] = { hook1, hook2 };

int main(void)
{
return 0;
}

int hook1(int a)
{
/* ... */
}

int hook2(char *b, double c)
{
/* ... */
}

C'est un compromis dans la mesure ou tu perds la verification du type
des arguments par le compilateur (puisque tes fonctions sont declarees
comme prenant un ensemble non specifie d'arguments).



ah j'ai le droit de ne pas spécifier les arguments ??? je savais pas...

le problème est que mon application n'etant pas encore développée, et que je
dois penser que je pourrai (et ferai sûrement) faire des rajout de fonctions
au serveur, je ne peux pas dire que le type de retour est le même, je dois
donc considérer que ça n'est pas le cas !

bon, le tableau a la base, c'est obligé, car il me sert d'index pour le
client... mais que mettre dedans ?
vu que les pointeurs sont différents, on ne peut les mettre directement dans
les cases...

dans mon délire, j'ai pensé a faire un tableau dont les cases contiendrait
une union qui elle même contient tous les types de pointeurs de
fonctions.... hum hum, il est temps de me sauver !! :o)


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com

Avatar
raffaello pelagalli
Nicolas aunai wrote:
Bertrand Mollinier Toublet a écrit:


Dans les grandes lignes, oui.

Mais...

Les pointeurs sur des fonctions de signature differente sont
*incompatibles*. Tu ne peux donc pas ranger dans le meme tableau un
pointeur sur une fonction prenant un int en argument et un pointeur
sur
une fonction prenant un double (par exemple). Ca limite
considerablement l'interet et le domaine d'application du truc.



c'est exactement sur celà que je me prend la tête depuis que j'ai tapé mon
précédent post !! :'(



Un compromis possible est que toutes les fonctions que tu utilises
aient
le meme type de retour, auquel cas tu peux utiliser un tableau de
pointeur sur des fonctions aux arguments non specifies et retournant
le
type commun:

typedef int (*hook)();

int hook1();
int hook2();

hook hook_table[2] = { hook1, hook2 };

int main(void)
{
return 0;
}

int hook1(int a)
{
/* ... */
}

int hook2(char *b, double c)
{
/* ... */
}

C'est un compromis dans la mesure ou tu perds la verification du type
des arguments par le compilateur (puisque tes fonctions sont declarees
comme prenant un ensemble non specifie d'arguments).




ah j'ai le droit de ne pas spécifier les arguments ??? je savais pas...

le problème est que mon application n'etant pas encore développée, et que je
dois penser que je pourrai (et ferai sûrement) faire des rajout de fonctions
au serveur, je ne peux pas dire que le type de retour est le même, je dois
donc considérer que ça n'est pas le cas !

bon, le tableau a la base, c'est obligé, car il me sert d'index pour le
client... mais que mettre dedans ?
vu que les pointeurs sont différents, on ne peut les mettre directement dans
les cases...

dans mon délire, j'ai pensé a faire un tableau dont les cases contiendrait
une union qui elle même contient tous les types de pointeurs de
fonctions.... hum hum, il est temps de me sauver !! :o)


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com


et avec une union, c pas possible ??

genre :
union {
int (*fct_qui_retourn_int)();
char (*fct_dui_retourn_char)();
} fcts_u;

et apres un truc du style:
fcts_u fcts[NB_DE_FCTS];

fcts[0].ftc_qui_retourn_int = ma_fct;
....

fcts[0].ftc_qui_retourn_int(ma_var);


Avatar
Nicolas aunai
raffaello pelagalli a écrit:

et avec une union, c pas possible ??
genre :
union {
int (*fct_qui_retourn_int)();
char (*fct_dui_retourn_char)();
} fcts_u;

et apres un truc du style:
fcts_u fcts[NB_DE_FCTS];

fcts[0].ftc_qui_retourn_int = ma_fct;
....

fcts[0].ftc_qui_retourn_int(ma_var);



voilà bah ct ça mon délire... un tableau d'union qui contiennent tous les
types de pointeurs possibles....

mais ça me semble un peu de la bidouille, bordélique comme truc....



--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com

Avatar
Michel BILLAUD
"Nicolas aunai" @free.fr> writes:

salut,

j'aimerai avoir un stratagème pour appeler dynamiquement une fonction...

j'ai pensé a mettre dans un tableau, des pointeurs pointant vers les
fonctions que je veux appeler, mais je ne voit pas comment executer une
fonction en manipulant un pointeur sur elle....


Exemple source :


#include <unistd.h>
#include <stdio.h>

void truc(int n) { printf("ici truc %dn",n); }
void machin(int n) { printf("ici machin %dn",n); }

int main()
{
void(*t[3])(int); // tableau de fonctions à parametre entier
int i;

t[0] = truc; t[1] = machin; t[2] = truc;

for (i=0;i<3;i++)
(*t[i])(1O+i);
exit(0);
}

Compilation: sans se faire engueuler par le compilateur !

:~$ gcc -Wall -pedantic fonc.c


Execution:

:~$ ./fonc
ici truc 0
ici machin 10
ici truc 20


--
Michel BILLAUD
LABRI-Universite Bordeaux I phone W: 05 4000 6922 / 05 4000 5792
351, cours de la Liberation http://www.labri.fr/~billaud
33405 Talence (FRANCE) http://dept-info.labri.fr/~billaud

Avatar
Richard Delorme
Bertrand Mollinier Toublet a écrit:

void(*t[3])(int); // tableau de fonctions à parametre entier
^^^

Ha, je ne pense pas non. Un caractere accentue dans un source C, c'est
pas tres portable (la preuve etant le resultat de la compilation par gcc).


Non. les caractères accentuées sont OK. gcc les tolères tout à fait dans les
commentaires. Et certains compilateurs récents (visual C++ 7.x) les
tolèrent de partout (nom de variable, etc...), comme l'autorise tout à fait
la norme.

[...]
$ gcc -W -Wall -pedantic -ansi main.c -o test
---------------------------^^^^^

À remplacer par -stdÉ9
Comme cela les commentaires de type : //...
passe.


--
Richard


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Nicolas aunai" @free.fr> wrote:

j'aimerai avoir un stratagème pour appeler dynamiquement une
fonction...


Heu, à quoi cela peut-il servir ?


bah dans le cas d'une application réseau, où un serveur possède des
fonctionnalités, un client peut s'y connecter et via un protocole
particulier envoyer des requetes pour executer certaines fonctions.

comme les requetes sont envoyées lors de l'execution de l'application, ce
sont des appels dynamiques aux fonctions du serveur qu'il faut faire.


Oui, c'est un bête shell...

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/



1 2 3 4