2010-12-20 5 views
0

Zuerst habe ich gesehen this (< - ein Link), und es funktioniert nicht. Ich bin mit OS X.Warum kann diese dynamisch geladene Bibliothek nicht auf die globalen Variablen des Ladeprogramms zugreifen?

A. C:

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

int global_var = 0x9262; 

int main(void) { 
    void *handle = dlopen("libb.so", RTLD_LAZY); 
    void (*func)(void); 
    char *err; 
    if (handle == NULL) { 
    fprintf(stderr, "%s\n", dlerror()); 
    return 1; 
    } 
    func = dlsym(handle, "func"); 
    if ((err = dlerror()) != NULL) { 
    fprintf(stderr, "%s\n", err); 
    return 2; 
    } 
    global_var = 0x9263; 
    func(); 
    return -dlclose(handle) * 3; 
} 

b.c:

#include <stdio.h> 

extern int global_var; 

void func(void) { 
    printf("0x%x\n", global_var); 
} 

Kompilieren und Ausführen:

$ gcc -shared -rdynamic -fpic -o liba.so a.c 
$ gcc -shared -fpic -o libb.so -L. -la b.c 
$ gcc -fpic -o a a.c 
$ ./a 
0x9262 

Warum es nicht 0x9263 drucken? Ich habe viele Kombinationen von Compiler-Flags ausprobiert, und keiner von ihnen funktioniert.

Antwort

3

Sie haben zwei Instanzen von global_var erstellt. Eines ist in liba.so definiert, und das ist das, das b.c referenziert.

Die andere ist in a definiert, und das ist die, die Ihre main() Funktion referenziert.

Wenn Ihre Hauptfunktion die Variable in liba.so referenzieren soll, benötigt sie eine extern Deklaration anstelle einer Definition, und sie muss mit dieser Bibliothek selbst verknüpft werden.

+0

+1 Genau (und einige mehr Zeichen) – slezica

0

Interessante Frage. Die Antwort ist auch interessant.

Wie in der Antwort von caf erwähnt, haben Sie zwei Definitionen von global_var erstellt.

Um zu tun, was Sie erreichen wollen, müssen Sie sicherstellen, dass global_var von der Hauptdatei ausgeführt wird. Dazu müssen Sie eine Importdatei erstellen, die besagt, dass global_var aus der Hauptdatei importiert wird. In der Importdatei sollten Sie #! Verwenden. dafür.

Verwenden Sie diese Importdatei beim Erstellen der Bibliothek.

Stellen Sie auch beim Kompilieren der Hauptbinärdatei sicher, dass die Variable global_var exportiert wird. Verwenden Sie entsprechende Compiler-Flags.

Auf meiner Unix-Box habe ich das versucht und es funktioniert.

+0

die # kommt nicht richtig in der Post – cexpert