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

Le
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.
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Laurent Wacrenier
Le #601159
Nicolas Hervé
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 ?

Nicolas Hervé
Le #601157
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 sub_fun_hello()
{
printf("hellon");
}


/* file youpi.c */
#include 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é
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 ?



Laurent Wacrenier
Le #601156
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.


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 sub_fun_hello()
{
printf("hellon");
}


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


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

Nicolas Hervé
Le #600946
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() ?

Yves ROMAN
Le #600945

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.

Nicolas Hervé
Le #600943
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.



Laurent Wacrenier
Le #600942
Nicolas Hervé
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.

Yves ROMAN
Le #600941

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 #include
/*** 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 ;
}


Nicolas Hervé
Le #600940
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 :-)


Laurent Wacrenier
Le #600939
Nicolas Hervé
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).

Publicité
Poster une réponse
Anonyme