Der MSVC-Linker kann Objektdateien (.obj) und Objektbibliotheken (.lib) verknüpfen, um eine .EXE- oder .DLL-Datei zu erstellen.
Um mit einer DLL zu verknüpfen, besteht der Prozess in MSVC darin, eine sogenannte Importbibliothek (.LIB) zu verwenden, die als Bindeglied zwischen den C-Funktionsnamen und der Exporttabelle der DLL fungiert (in einer DLL kann eine Funktion namentlich oder nach Ordnungszahl - Letzteres wurde oft für undokumentierte APIs verwendet).
In den meisten Fällen enthält die DLL-Exporttabelle jedoch alle Funktionsnamen und somit enthält die Importbibliothek (.LIB) weitgehend redundante Informationen ("Importfunktion ABC -> exportierte Funktion ABC ", etc).
Es ist sogar möglich, eine .LIB aus einer bestehenden .DLL zu generieren.
Linker auf anderen Plattformen haben diese "Funktion" nicht und können direkt mit dynamischen Bibliotheken verknüpfen.
Unter Linux durchsucht der Linker (nicht der dynamische Linker) die gemeinsam genutzten Bibliotheken, die zum Linkzeitpunkt angegeben wurden, und erstellt Verweise darauf innerhalb der ausführbaren Datei. Wenn der dynamische Linker diese ausführbaren Dateien lädt, lädt er die gemeinsam genutzten Bibliotheken, die sie benötigen, in den Arbeitsspeicher und löst die Symbole auf, wodurch die Binärdateien ausgeführt werden können.
MySo.a
, wenn erstellt, würde tatsächlich die zu verknüpfenden Symbole direkt in die Binärdatei einschließen, anstatt der "Symbol-Nachschlagetabellen", die unter Windows verwendet werden.
Die Antwort von rustyx erklärt den Prozess unter Windows gründlicher als ich es kann; es ist lange her, dass ich Windows verwendet habe.
Der Unterschied, den Sie sehen, ist eher ein Implementierungsdetail - unter der Haube funktionieren sowohl Linux als auch Windows ähnlich - Ihr Code ruft eine Stub-Funktion auf, die statisch in Ihrer ausführbaren Datei verknüpft ist, und dieser Stub lädt dann bei Bedarf DLL/shlib (im Falle einer verzögerten lädt, sonst wird Bibliothek beim Programmstart geladen) und (beim ersten Aufruf) Symbol über GetProcAddress
aufgelöst /dlsym
.
Der einzige Unterschied besteht darin, dass diese Stub-Funktionen (die PLT-Stubs genannt werden) unter Linux dynamisch generiert werden wenn Sie Ihre App mit einer dynamischen Bibliothek verknüpfen (die Bibliothek enthält genügend Informationen, um sie zu generieren), während sie unter Windows stattdessen generiert werden, wenn die DLL selbst erstellt wird, in einem separaten .lib
Datei.
Die beiden Ansätze sind so ähnlich, dass es tatsächlich möglich ist, Windows-Importbibliotheken unter Linux nachzuahmen (siehe Implib.so-Projekt).