[Précédent (date)] [Suivant (date)] [Précédent (sujet)] [Suivant (sujet)] [Index par date] [Index par sujet]

Appel d'une fonction présente dans la DLL et dans le prog. principal



J'ai un problème avec l'appel d'une fonction dans une librairie
chargée dynamiquement.

Il y a une fonction, disons pizza(), qui existe dans le programme
principal ainsi que dans la librairie qu'il charge. Quand un bout
de code dans la librairie veut appeler la fonction pizza() de la
librairie elle-même, c'est en fait la fonction pizza() du
programme principal qui est appelée.

Je me demande comment faire en sorte que ce soit la version de pizza()
de la librairie qui soit celle qui est appelée dans cette situation.

Dans l'exemple suivant, les lignes affichées sont:

    prog.c:pizza()
    calling message(): Hello, world.

alors qu'en fait la première ligne devrait être "message.c:pizza()".

Voici le programme principal (prog.c):

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

void pizza()
{
    printf("prog.c:pizza()\n");
}

int main(int argc, char **argv)
{
    void *handle;
    const char *(*function)(void);
    const char *error;
    const char *libname = "./libmessage.so";

    handle = dlopen(libname, RTLD_LAZY);
    if (handle == NULL) {
        fprintf(stderr, "dlopen(%s): %s\n", libname, dlerror());
        exit(1);
    }

    function = dlsym(handle, "message");
    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "dlsym(message): message(): %s\n", error);
        exit(1);
    }
    printf ("calling message(): %s\n", (*function)());

    dlclose(handle);

    return 0;
}
----------------------------------------------------------------------


Voici le fichier source qui constitue la librairie (message.c):

----------------------------------------------------------------------
void pizza()  // should be called by message()
{
    printf("message.c:pizza()\n");
}

const char *message(void)
{
    static char buffer[128];

    pizza();  // this should call the pizza() function in this file
    sprintf(buffer, "Hello, world.");
    return buffer;
}
----------------------------------------------------------------------


Voici comment j'ai créé le programme principal et sa librairie:

gcc -rdynamic -o prog prog.c -ldl
gcc -fPIC -c message.c
gcc -shared message.o -o libmessage.so

Pour exécuter, il suffit de taper `./prog'.

J'utilise un système RedHat Linux 5.2 sur un Pentium avec "gcc version
egcs-2.91.66 19990314 (egcs-1.1.2 release)", que j'ai compilé et
installé moi-même.

Le linker est "GNU ld version 2.9.1 (with BFD 2.9.1.0.15)".
La librairie du C est glibc 2.0.7.