2010-12-10 2 views
6

Wenn ich eine gemeinsame Bibliothek (gemeinsames Objekt) erstellen kann ich auf zwei Arten verwenden:
Erste Möglichkeit ist die Verwendung einer gemeinsam genutzten Bibliothek wie ich eine statische Bibliothek verwenden würde.Dilemma über gemeinsam genutzte Bibliotheken unter Unix

  #include "myLib.h" 
      //... 
      //afterwards I can use functions defined in mylib.h 
      myFunction(); 

Die zweite Möglichkeit der gemeinsamen Bibliothek ist von Dynamic Loader API-Funktionen aufrufen: dlopen, dlsym und dlclose von dlfcn.h. Ich würde die shared library auf diese Weise verwenden, wenn ich zum Beispiel ein Plugin-Muster implementieren möchte. Eintrag würde wie folgt aussehen:

#include <dlfcn.h> 

void *myLib;    /* Handle to shared lib file */ 
void (*myFunction)();  /* Pointer to loaded function */ 

    //... 

    //load shared object 
    myLib = dlopen("/home/dlTest/myLib.so",RTLD_LAZY); 
    dlerror(); 

    //get handle to function 
    myFunction = dlsym(myLib, "myFunction"); 
    dlerror(); 

    //execute function 
    (*myFunction)(); 

    //close lib 
    dlclose(myLib); 
    dlerror(); 

Nun meine erste Frage ist: Was ist der Unterschied zwischen diesen beiden Verwendungen des gemeinsam genutzten Objekts in Bezug auf die Ladezeit? Wenn wir die shared library auf die erste Art verwenden, verlinken/laden wir die shared library in der Ladezeit mit der main app und auf die zweite Weise machen wir dasselbe in der Laufzeit.

Zweite Frage. Wie heißen diese beiden Nutzungen? Die erste wird als statisch verknüpfte shared library und die zweite als dynamisch verknüpfte/geladene shared library bezeichnet.

Dritte Frage Wenn ich eine shared library ohne -fPIC flag (oition unabhängigen Code) gebaut habe, wäre ich in der Lage, es auf eine zweite Weise zu verwenden?

Prost

Antwort

4

Diese beiden Verwendung Modi werden in der Regel implizite und explizite genannt. Wie Sie richtig festgestellt haben, besteht der Unterschied beim Laden darin, dass die explizit verknüpfte dynamische Bibliothek geladen wird, wenn dlopen ausgeführt wird und die implizit verknüpfte Bibliothek zu dem Zeitpunkt geladen wird, zu dem die Anwendung in den Speicher geladen wird. Jedes dlopen kann einige Millisekunden dauern, bis die Bibliothek bereits geladen ist. In diesem Fall ist es sehr schnell. Wenn Sie also sehr strenge Latenzanforderungen haben oder häufig laden/entladen müssen, können Sie die Verknüpfung implizit oder explizit laden Beim Programmstart und nicht entladen, bis es nicht mehr verwendet wird.

+0

Wenn ich eine gemeinsam genutzte Bibliothek ändere und neu kompiliere, muss ich alle Hauptanwendungen neu verknüpfen, die diese freigegebene Bibliothek verwenden, wenn ich implizite Verknüpfungen verwende, oder wenn diese Anwendungen automatisch geladen werden? –

5

Der Hauptunterschied liegt in der Fehlerbehandlung. Implizit ist einfacher, aber wenn es ein Problem gibt (die Bibliothek fehlt oder die Funktion ist nicht in der Bibliothek), wird das Programm überhaupt nicht ausgeführt. Beim expliziten Laden können Sie die dlopen/dlsym-Aufrufe auf Fehler überprüfen und bei Problemen auf eine Alternative zurückgreifen.

Um Ihre dritte Frage zu beantworten, hängt es tatsächlich von der Architektur ab, aber auf den meisten ABIs können Sie immer noch ein gemeinsam genutztes Objekt ohne -PIC laden, aber es kann langsamer geladen werden und mehr Speicher benötigen.

+0

Wenn ich eine gemeinsam genutzte Bibliothek ändere und neu kompiliere, muss ich alle Hauptanwendungen, die diese freigegebene Bibliothek verwenden, neu verknüpfen, wenn ich implizite Verknüpfungen verwende oder wenn diese Anwendungen automatisch geladen werden? –

+0

@ kobac: no - shared libraries sind immer verbunden, wenn sie geladen werden, entweder beim Start der Anwendung oder beim Aufruf von dlopen –