2015-01-07 2 views
8

Ich schaute auf diese Seite: An In-Depth Look into the Win32 Portable Executable File FormatWie funktionieren Import-Bibliotheken und warum benötigt MinGW sie nicht?

Es erklärt, dass der Linker eine Importbibliothek benötigt, da der Compiler nicht zwischen normalen Funktionsaufrufen und API-Funktionsaufrufen unterscheiden kann. Aber sie sagen auch, dass __declspec (dllimport) einen Funktionsaufruf als API-Aufruf spezifiziert, so dass der Linker gegen __imp_[function-name] verlinkt. Aber mit diesem Schlüsselwort sollte der Compiler wissen, dass dies ein Aufruf einer API-Funktion ist.

Warum benötigt der Linker noch eine Importbibliothek? Der Compiler könnte dieses Symbol als importiert markieren, indem er dem Funktionsnamen __imp_ voranstellt und einen Funktionszeiger aufrufen könnte (der noch ein ungelöstes Symbol ist), und der Linker könnte dieses Symbol ersetzen (weil er sieht, dass dies ein API-Aufruf ist) die Adresse des IAT-Eintrags.

Und warum kann der MinGW-Linker "MinGW-DLLs" direkt verwenden, aber der Visual-Studio-Linker benötigt eine Import-Bibliothek?

Als ich den Beitrag las, wurden auch andere Fragen aufgeworfen. Wie kennt das "dlltool (oder linker)" (was auch immer die Import-Bibliothek erstellt) den Speicherort eines IAT-Eintrags, bevor die Verknüpfung mit der endgültigen ausführbaren Datei hergestellt wurde? Ich dachte, die IAT-Einträge würden bei der Link-Zeit mit der endgültigen ausführbaren Datei erstellt werden. Der Post sagte, dass jeder API-Aufruf eine feste Position in der IAT-Tabelle hat, egal wie viele DLLs verknüpft werden. Ich kann mir nicht vorstellen, wie das erreicht werden könnte.

+0

[Dieser Beitrag] (http://stackoverflow.com/a/3573527/1881610) beantwortet die meisten Ihrer Fragen. – Phillip

Antwort

11

Es ist möglich, zu DLL ohne eine Importbibliothek zu verknüpfen, wie MinGW deutlich zeigt. Daher ist die Frage, warum MSVC entschied, diese Funktion zu überspringen.

Die Gründe sind in erster Linie historisch.

Damals, 1983, als Windows auf den Markt kam und DLLs entwickelt wurden, gab es viele Toolchains (Compiler, Linker) verschiedener Hersteller. Auszugehen, die Hersteller zu bitten, die Unterstützung für das Verknüpfen von "DLLs" für ein Betriebssystem von Minderheiten zu implementieren, war eindeutig keine Option.

Also beschlossen sie, ein Werkzeug zu schreiben, um eine Bibliothek zu erstellen, die jeder und ihr Hund verlinken konnte, selbst wenn ein Linker absolut keine Ahnung von DLLs hatte.

Neben Import-Bibliotheken bieten einige Funktionen, die vor 3 Jahrzehnten lebenswichtig waren, aber jetzt neben veraltet sind. Erstens ist die Fähigkeit, ein Symbol nach Ordinalzahl zu importieren - d. H. DLL hat eine Option, um nur eine Liste von Adressen überhaupt keine Namen anzubieten; Die Ordinalzahl ist ein Index in dieser Liste. Sinn gemacht, wenn die Menge an RAM stark eingeschränkt war.

Zweitens ist die Unterstützung für verschiedene Namen Mangeln Schemata. Sogar in C gibt es ein Namens-Mangling-Schema, zum Beispiel kann FooBar _FooBar @ 4 werden (es hängt von der Plattform und der Aufrufkonvention ab). Es macht durchaus Sinn, dass eine DLL "FooBar" auf jeder unterstützten Plattform aus Konsistenzgründen exportiert (und das Leben des GetProcAddress() - Benutzers einfacher macht). Import-Bibliothek implementiert das Mapping von _FooBar @ 4 zu FooBar.

Dies basiert auf dem Blog (1, 2) von Raimond Chen, der Mann, der von Anfang an in Windows-Entwicklung beteiligt war.

+0

Wo kann ich mehr Details darüber finden, was genau in der Import-Bibliothek enthalten ist und wie es in Link-Zeit, Ladezeit und Laufzeit funktioniert? – Youda008