Gemeinsam genutzte Bibliotheken und .h-Dateien

7

Ich habe einige Zweifel darüber, wie Programme Shared Library verwenden.

Wenn ich eine shared library (mit -shared -fPIC-Switches) erstelle, stelle ich einige Funktionen von einem externen Programm zur Verfügung. Normalerweise mache ich eine dlopen (), um die Bibliothek zu laden, und dann dlsym (), um die besagten Funktionen mit einigen Funktionszeigern zu verknüpfen. Bei diesem Ansatz wird keine H-Datei einbezogen. Gibt es eine Möglichkeit zu vermeiden, dlopen () & amp; dlsym () und nur einschließlich der .h der Shared Library?

Ich rate das könnte sein, wie C ++ - Programme Code verwenden, der in der System-Shared-Library gespeichert ist. Dh einfach einschließlich stdlib.h etc.

    
nick2k3 24.07.2009, 08:36
quelle

4 Antworten

37

Nick, ich denke, alle anderen Antworten beantworten tatsächlich Ihre Frage, nämlich wie Sie Bibliotheken verknüpfen, aber die Art, wie Sie Ihre Frage formulieren, legt nahe, dass Sie den Unterschied zwischen Header-Dateien und Bibliotheken falsch verstanden haben. Sie sind nicht gleich. Du brauchst beide und sie machen nicht dasselbe.

Das Erstellen einer ausführbaren Datei hat zwei Hauptphasen: die Kompilierung (die Ihre Quelle in eine Zwischenform umwandelt, die ausführbare binäre Anweisungen enthält, aber kein ausführbares Programm ist) und die Verknüpfung (die diese Zwischendateien zu einer ausführbaren Datei oder Bibliothek zusammenfasst) ).

Wenn Sie gcc -c program.c erstellen, kompilieren Sie und Sie generieren program.o . In diesem Schritt sind Header wichtig. Sie müssen #include <stdlib.h> in program.c verwenden, um (zum Beispiel) malloc und free zu verwenden. (Ähnlich brauchen Sie #include <dlfcn.h> für dlopen und dlsym .) Wenn Sie das nicht tun, wird der Compiler beschweren, dass er nicht weiß, was diese Namen sind, und mit einem Fehler anhalten. Wenn Sie jedoch #include eingeben, fügt der Compiler nicht den Code für die aufgerufene Funktion in program.o ein. Es fügt nur eine Referenz hinzu. Der Grund dafür ist die Vermeidung von Codeverdopplungen: Auf den Code muss nur einmal von jedem Teil Ihres Programms zugegriffen werden, wenn Sie also weitere Dateien benötigen ( module1.c , module2.c usw.), selbst wenn sie < em> all verwendet malloc Sie würden nur mit vielen Verweisen auf eine einzelne Kopie von malloc enden. Diese einzelne Kopie ist in der standardmäßigen library entweder in der freigegebenen oder statischen Form ( libc.so oder libc.a ) vorhanden, aber diese werden in Ihrer Quelle nicht referenziert, und der Compiler erkennt sie nicht.

Der Linker ist . In der Verknüpfungsphase machst du gcc -o program program.o . Der Linker durchsucht dann alle Bibliotheken, die Sie an der Befehlszeile übergeben, und findet die einzige Definition aller Funktionen, die Sie aufgerufen haben und die nicht in Ihrem eigenen Code definiert sind. Das ist, was die -l tut (wie die anderen erklärt haben): Teilen Sie dem Linker die Liste der Bibliotheken mit, die Sie verwenden müssen. Ihre Namen haben oft wenig mit den Überschriften zu tun, die Sie im vorherigen Schritt verwendet haben. Um beispielsweise dlsym zu verwenden, benötigen Sie libdl.so oder libdl.a . Ihre Befehlszeile lautet also gcc -o program program.o -ldl . Um malloc oder die meisten Funktionen in den std*.h -Headern zu verwenden, benötigen Sie libc . Da diese Bibliothek jedoch von jedem C-Programm verwendet wird, ist sie automatisch verknüpft (als hättest du -lc gemacht).

Tut mir leid, wenn ich auf viele Details eingehe, aber wenn du den Unterschied nicht kennst, den du willst. Es ist sehr schwer zu verstehen, wie die C-Kompilierung funktioniert, wenn Sie dies nicht tun.

Eine letzte Sache: dlopen und dlsym sind nicht die normale Methode der Verknüpfung. Sie werden für spezielle Fälle verwendet, in denen Sie anhand von Informationen, die aus irgendeinem Grund nur zur Laufzeit verfügbar sind, dynamisch ermitteln möchten, welches Verhalten Sie wünschen. Wenn Sie wissen, welche Funktionen Sie zur Kompilierzeit aufrufen möchten (in 99% der Fälle), müssen Sie die dl* -Funktionen nicht verwenden.

    
quark 27.07.2009, 07:10
quelle
3

Sie können gemeinsam genutzte Bibliotheken wie statische Bibliotheken verknüpfen. Sie werden dann beim Starten des Programms gesucht. In der Tat wird -lXXX standardmäßig libXXX.so zu libXXX.a vorziehen.

    
AProgrammer 24.07.2009 08:42
quelle
2

Sie müssen dem Linker die richtigen Anweisungen zum Verknüpfen Ihrer gemeinsam genutzten Bibliothek geben.

Die Namen der gemeinsam genutzten Bibliotheken sind wie libNAME.so. Um sie zu verlinken, sollten Sie -lNAME

verwenden

Nennen Sie es libmysharedlib.so und verknüpfen Sie dann Ihr Hauptprogramm als:

%Vor%     
Arkaitz Jimenez 24.07.2009 08:42
quelle
1

Wenn Sie CMake verwenden, um Ihr Projekt zu erstellen, können Sie

verwenden %Vor%

Wie in:

%Vor%

Um die Bibliothek "mylibrary" zu erstellen, können Sie

verwenden %Vor%

Wie in:

%Vor%

Außerdem ist diese Methode plattformübergreifend (während das Übergeben von Flags an gcc einfach nicht möglich ist).

    
Michael Aaron Safyan 27.07.2009 02:51
quelle

Tags und Links