Ich habe diese Seite angeschaut: Ein ausführlicher Einblick in das ausführbare Dateiformat von Win32 Portable
Es wird erläutert, 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 __imp_
dem Funktionsnamen 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) ) mit der 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 noch andere Fragen gestellt. 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.
Es ist möglich, eine DLL ohne eine Importbibliothek zu verknüpfen, wie MinGW deutlich zeigt. Daher ist die Frage, warum MSVC entschieden hat, dieses Feature wegzulassen.
Die Gründe sind in erster Linie historisch.
Damals, 1983, als Windows erschien und DLLs entwickelt wurden, gab es viele Toolchains (Compiler, Linker) von verschiedenen Herstellern. Auszugehen, die Hersteller zu bitten, die Unterstützung für das Verknüpfen von "DLLs" für ein Betriebssystem mit Minderheiten zu implementieren, war eindeutig keine Option.
Also haben sie eine Entscheidung getroffen, ein Tool zu schreiben, mit dem sie eine Bibliothek erstellen können, die jeder und ihr Hund verlinken könnte, auch wenn ein Linker absolut keine Ahnung von DLLs hat.
Außerdem bieten Import-Bibliotheken einige Funktionen, die vor drei Jahrzehnten noch wichtig waren, aber jetzt schon 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, dem Mann, der an der Windows-Entwicklung von der. beteiligt war ganz am Anfang.