Apprenons en quelques lignes à appeler des fonctions du propre executable en utilisant les possibilités qu'offre DLFCN(3). Ceci permettra entre autres d'appeler des fonctions dont le nom aura été construit dynamiquement.

Vous connaissez peut-être la primitive dlopen() qui permet de charger des librairies dynamiques pendant le runtime :

void *hdl;
int (*sbl)(int);
 
if ((hdl = dlopen("libtoto.so", RTLD_LAZY)) == NULL)
    errx(EXIT_FAILURE, "Cannot open library: %s.", dlerror());
 
if ((sbl = dlsym(hdl, "toto_fonction")) == NULL) {
    dlclose(hdl);
    errx(EXIT_FAILURE, "no such function %s\n", "toto_fonction");
}
(sbl)(10);
 
dlclose(hdl);
Methode 1

La lecture attentive du man dlopen nous apprend ceci :

If the first argument is NULL, dlopen() returns a handle on the
global symbol object. This object provides access to all symbols from
an ordered set of objects consisting of the original program image and
any dependencies loaded during startup.

En clair, si l'on passe NULL comme premier argument à dlopen() et que l'on compile avec le flag -rdynamic, on peut appeler un symbole du programme courant de la même manière que dans l'exemple précédent :

int
fonction_tata(int t)
{
    printf("bleh\n");
}
[...]
int
main(int argc, char *argv[])
{
[...]
    hdl = dlopen(NULL, RTLD_GLOBAL);
 
    if ((sbl = dlsym(hdl, "fonction_tata")) == NULL) {
        dlclose(hdl);
        errx(EXIT_FAILURE, "no such function %s\n", cmd);
    }
 
    rc = (sbl)(10);
 
    dlclose(hdl);
[...]
}

Merci Palats pour ce tip :)

Methode 2

La lecture attentive du fichier /usr/include/dlfcn.h nous apprend l'existence de ces 3 defines :

/*
 * Special handle arguments for dlsym().
 */
#define RTLD_NEXT       ((void *) -1)   /* Search subsequent objects. */
#define RTLD_DEFAULT    ((void *) -2)   /* Use default search algorithm. */
#define RTLD_SELF       ((void *) -3)   /* Search the caller itself. */

Dans le cas qui nous interesse, un simple appel à dlsym() avec en premier argument RTLD_SELF et en second argument le symbole recherché permettra d'obtenir le même résultat que dans la methode 1. L'utilisation de dlopen() est inutile dans ce cas :

int
fonction_tata()
{
    printf("pwet\n");
}
 
int
main(int argc, char *argv[])
{
    int (*sbl)(void);
 
[...]
    if ((sbl = dlsym(RTLD_SELF, "fonction_tata")) == NULL)
        errx(EXIT_FAILURE, "no such function %s\n", cmd);
[...]
}

Notez qu'il ne faut pas non plus utiliser dlclose() puisqu'aucun handler n'a été ouvert par un dlopen()

Merci à spoty pour ce tip :)

c/dlopen_self.txt · Last modified: 2010/01/12 13:29 (external edit)
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0