Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Passer en argument le nom d'une fonction à exécuter

11 réponses
Avatar
Nicolas Hervé
Je veux passer en option à ma fonction principale le nom d'une fonction
secondaire qui sera utilisé pour une certaine action.
Le but est de pouvoir choisir à l'exécution quel algo on va pouvoir
utiliser.

Ces fonctions secondaire seront dans une librairie chargé dynamiquement.

En quelque sorte je souhaite développer une API avec déjà quelques algos
implémentés pour ma fonction secondaire et permettre à l'utilisateur
d'étendre à d'autres algos.

10 réponses

1 2
Avatar
Laurent Wacrenier
Nicolas Hervé écrit:
Je veux passer en option à ma fonction principale le nom d'une fonction
secondaire qui sera utilisé pour une certaine action.


Quelle est la question ?

Avatar
Nicolas Hervé
La question est comment faire ?
Si on peut me donner un petit programme avec mainfile genre ce qui suit
ce serait génial.


/* file main.c */
int main (int argc, char **argv)
{
// comment exécuter argv[2] ?
}


/* file hello.c */
#include <stdio.h>
sub_fun_hello()
{
printf("hellon");
}


/* file youpi.c */
#include <stdio.h>
sub_fun_youpi()
{
printf("youpin");
}


/* file makefile */

SelectSubFun: libtestlib.so
gcc -Llib -ltest -o $@ main.c

libtestlib.so: hello.c youpi.c
gcc -fPIC -c $<
gcc -shared -o lib/libtestlib.so *.o



/* file test.sh */
#!/bin/sh
LD_LIBRARY_PATH=./lib:LD_LIBRARY_PATH
make
./SelectSubFun sub_fun_hello
# affiche "hello"
./SelectSubFun sub_fun_youpi
# affiche "youpi"


MakeLib :
Laurent Wacrenier wrote:

Nicolas Hervé écrit:

Je veux passer en option à ma fonction principale le nom d'une fonction
secondaire qui sera utilisé pour une certaine action.



Quelle est la question ?



Avatar
Laurent Wacrenier
Nicolas Hervé écrit:
La question est comment faire ?
Si on peut me donner un petit programme avec mainfile genre ce qui suit
ce serait génial.


Rien de portable. Avec POSIX on peut utiliser dlopen()/dlsym().

/* file main.c */
int main (int argc, char **argv)
{
// comment exécuter argv[2] ?
}


/* file hello.c */
#include <stdio.h>
sub_fun_hello()
{
printf("hellon");
}


/* file youpi.c */
#include <stdio.h>
sub_fun_youpi()
{
printf("youpin");
}


Les fonctions peuvent avoir le même nom.
Ça évite de le calculer.

Avatar
Nicolas Hervé
Laurent Wacrenier wrote:

Les fonctions peuvent avoir le même nom.
Ça évite de le calculer.



Effectivement les fonctions peuvent avoir le même nom, mais dans ce cas
çà oblige à créer des librairies différentes et à refaire une édition de
lien (ou à modifier un lien symbolique vers la bonne librairie) à chaque
fois qu'on veut changer d'implémentation. Non ?

Mes fonctions secondaires sont des algos d'optimisation. Suivant le
compromis recherché, l'utilisateur pourra choisir par exemple un
algorithme qui converge rapidement vers une solution acceptable ou
plutôt un algorithme plus lent mais qui offrira une solution de
meilleure qualité.

Comment fonctionnent dlopen()/dlsym() ?

Avatar
Yves ROMAN

Je veux passer en option à ma fonction principale le nom d'une fonction
secondaire qui sera utilisé pour une certaine action.
Le but est de pouvoir choisir à l'exécution quel algo on va pouvoir
utiliser.

Ces fonctions secondaire seront dans une librairie chargé dynamiquement.

En quelque sorte je souhaite développer une API avec déjà quelques algos
implémentés pour ma fonction secondaire et permettre à l'utilisateur
d'étendre à d'autres algos.


Ca dépend de ta plateforme :
ex sous Solaris (et peut-être d'autres Unix) voir dlopen(), dlsym()

En C standard, dans ta librairie dynamique, rajoute une fonction qui donne
l'adresse d'une fonction à partir de son nom : elle se base sur un tableau qui
contient une liste de couples { char * , void (*)() } des fonctions de la
librairie.

Avatar
Nicolas Hervé
Ok pour dlopen(), dlsym(), dlclose() en C pure (pas ++).
Je vais essayer ca dans un premier temps.

Par contre, je ne comprends pas la solution en C standard, et je ne
saurrait pas écrire une fonction qui donne l'adresse d'une autre à
partir de son nom.

Yves ROMAN wrote:


Je veux passer en option à ma fonction principale le nom d'une fonction
secondaire qui sera utilisé pour une certaine action.
Le but est de pouvoir choisir à l'exécution quel algo on va pouvoir
utiliser.

Ces fonctions secondaire seront dans une librairie chargé dynamiquement.

En quelque sorte je souhaite développer une API avec déjà quelques algos
implémentés pour ma fonction secondaire et permettre à l'utilisateur
d'étendre à d'autres algos.



Ca dépend de ta plateforme :
ex sous Solaris (et peut-être d'autres Unix) voir dlopen(), dlsym()

En C standard, dans ta librairie dynamique, rajoute une fonction qui donne
l'adresse d'une fonction à partir de son nom : elle se base sur un tableau qui
contient une liste de couples { char * , void (*)() } des fonctions de la
librairie.



Avatar
Laurent Wacrenier
Nicolas Hervé écrit:
Effectivement les fonctions peuvent avoir le même nom, mais dans ce cas
çà oblige à créer des librairies différentes et à refaire une édition de
lien (ou à modifier un lien symbolique vers la bonne librairie) à chaque
fois qu'on veut changer d'implémentation. Non ?


Quel est l'interêt de lier dynamquement à l'execution alors que tout
est dans le même fichier ?

Mes fonctions secondaires sont des algos d'optimisation. Suivant le
compromis recherché, l'utilisateur pourra choisir par exemple un
algorithme qui converge rapidement vers une solution acceptable ou
plutôt un algorithme plus lent mais qui offrira une solution de
meilleure qualité.


Heu.. êtes vous sûr que vous voulez des librairies dynamiques alors
qu'un simple pointeur de fonction ferait l'affaire.

Comment fonctionnent dlopen()/dlsym() ?


C'est indiqué dans le manuel.

Avatar
Yves ROMAN

Ok pour dlopen(), dlsym(), dlclose() en C pure (pas ++).
Je vais essayer ca dans un premier temps.

Par contre, je ne comprends pas la solution en C standard, et je ne
saurrait pas écrire une fonction qui donne l'adresse d'une autre à
partir de son nom.

Yves ROMAN wrote:

En C standard, dans ta librairie dynamique, rajoute une fonction qui donne
l'adresse d'une fonction à partir de son nom : elle se base sur un tableau qui
contient une liste de couples { char * , void (*)() } des fonctions de la
librairie.



Exemple:

#include <stdio.h>
#include <stdlib.h>

/*** Dans la librairie ***/

int mon_mult2 ( int param )
{
return 2*param ;
}

int mon_add3 ( int param )
{
return 3+param ;
}

typedef int t_fct (int) ;

typedef struct
{
char *nom ;
t_fct *fct ;
} t_carac_fct ;

t_carac_fct liste_fct[] {
{ "mon_mult2",mon_mult2 } ,
{ "mon_add3",mon_add3 } ,
{ NULL, NULL }
} ;

t_fct * cherche ( char * nom )
{
t_carac_fct * ps ;

for ( ps = liste_fct ; ps->nom != NULL ; ps++ )
{
if ( strcmp(ps->nom,nom) == 0 )
{
return ps->fct ;
}
}

return NULL ;
}


/*** dans le programme ***/

int applique ( char * nom , int val )
{
t_fct *pfct ;
int res ;

pfct = cherche(nom) ;
if ( pfct == NULL )
{
printf("Fonction %s inconnuen",nom) ;
return -1 ;
}

res = pfct(val) ;
printf("%s(%d)=%dn",nom,val,res) ;
return res ;
}

int main ( void )
{

applique("toto",2) ;
applique("mon_mult2",2) ;
applique("mon_add3",2) ;
return EXIT_SUCCESS ;
}


Avatar
Nicolas Hervé
Laurent Wacrenier wrote:


Quel est l'interêt de lier dynamquement à l'execution alors que tout
est dans le même fichier ?


J'ai pas compris toute suite le sens de la question (et encore je ne
suis pas sure d'avoir bien saisi)
Oui effectivement, les différentess fonctions que j'implémentent
seraient bien toutes dans la même librairie.


Heu.. êtes vous sûr que vous voulez des librairies dynamiques alors
qu'un simple pointeur de fonction ferait l'affaire.


Si le nombre de fonctions est figé et qu'il n'y a pas besoin d'en
rajouter oui mais si on veut permettre à l'utilisateur d'ajouter les
siennes, les librairies dynamiques me semblent plus appropriées.

Maintenant qu'est il usage de faire dans ce cas ?
En gros, les procédures d'optimisation viennent comme un plug-in sur
l'application générale.

NB: je n'ai jamais manipulé de pointeurs de fonctions.

Comment fonctionnent dlopen()/dlsym() ?



C'est indiqué dans le manuel.


Comme oujours RTFM :-)


Avatar
Laurent Wacrenier
Nicolas Hervé écrit:
J'ai pas compris toute suite le sens de la question (et encore je ne
suis pas sure d'avoir bien saisi)
Oui effectivement, les différentess fonctions que j'implémentent
seraient bien toutes dans la même librairie.


Alors il faudra saisir le nom de la librairie et le nom de la
fonction (c'est à dire les paramêtres pour dlopen et dlsym).

1 2