Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wichtig
Die Informationen in diesem Thema gelten für alle Versionen von Windows 10 und höher. Wir bezeichnen diese Versionen hier als "Windows", wobei bei Bedarf Ausnahmen genannt werden.
API-Sätze basieren auf der Betriebssystemunterstützung im Bibliotheksladeprogramm, um eine Modulnamespaceumleitung in den Bibliotheksbindungsprozess einzuführen. Ein API-Satz-Vertragsname behebt keinen Namen für eine Datei. Das Ladeprogramm führt eine Laufzeitumleitung von diesem Vertragsnamen zur Host-Binärdatei aus, die die Implementierung enthält.
Wenn das Ladeprogramm zur Laufzeit auf eine Abhängigkeit von einem API-Satz stößt, konsultiert es Konfigurationsdaten im Image, um die Host-Binärdatei für diesen API-Satz zu identifizieren. Diese Konfigurationsdaten werden als API-Set-Schemabezeichnet. Das Schema wird als Eigenschaft des Betriebssystems zusammengestellt, und die Zuordnung zwischen API-Sätzen und Binärdateien kann abhängig davon variieren, welche Binärdateien auf einem bestimmten Gerät enthalten sind. Mit dem Schema kann eine importierte Funktion in einer einzelnen Binärdatei auf verschiedenen Geräten ordnungsgemäß weitergeleitet werden, auch wenn das Modul, das die Implementierung hostet, umbenannt, aufgeteilt oder umgestaltet wurde.
Wie Importe eine Implementierung erreichen
Eine Binärdatei kann eine API-Satzimplementierung auf zwei Arten erreichen, die durch den Namen in der Importtabelle entschieden wird:
- Direkter API-Satzimport. Die Binärdatei importiert einen API-Satz-Vertragsnamen. Das Ladeprogramm löst diesen Namen über das API-Set-Schema in die Host-Binärdatei auf dem aktuellen Gerät auf.
- Legacymodulimport. Die Binärdatei importiert einen älteren Windows Modulnamen, z. B. samplefeature.dll. Bei einer Edition, die dieses Modul enthält, bindet das Ladeprogramm direkt an das Modul. Bei einer Edition, die sie ersetzt hat, leitet ein Reverse-Weiterleitungsmodul mit demselben Namen den Import zu einem API-Satz um, der vom Ladeprogramm dann durch das Schema aufgelöst wird.
Welche dieser Namen in Ihrer Importtabelle enden, hängt in der Regel von der Bibliothek ab, mit der Sie eine Verknüpfung herstellen, und nicht von der Quelle, mit der Sie schreiben. Siehe Windows Dachbibliotheken.
Bevorzugen Sie den API-Satz-Vertragsnamen für Code, der auf aktuelle Versionen von Windows ausgerichtet ist. Der Ladevorgang wird direkt auf den Host aufgelöst, ohne dass zwischen dem Weiterleitungsmodul. Importieren Sie den Namen des Legacymoduls, wenn Sie eine einzelne Binärdatei benötigen, die auch auf Windows Versionen ausgeführt wird, die veröffentlicht wurden, bevor der API-Satz vorhanden ist. Die Reverseweiterleitung behält bei, dass die binäre Arbeit an Editionen funktioniert, in denen das Legacymodul ersetzt wurde.
Direct API Set Import
Die Auflösung ist eine dreistufige Sequenz:
- Ihre Binärdatei importiert einen API-Satz-Vertragsnamen oder übergibt einen an LoadLibrary.
- Das Ladeprogramm sucht den Vertrag im API-Set-Schema auf dem aktuellen Gerät und findet die Host-Binärdatei, der das Schema zugeordnet ist.
- Das Ladeprogramm lädt die Host-Binärdatei und bindet die importierte Funktion an den Export des Hosts.
Da sich die Zuordnung nicht im Dateisystem, sondern im Schema befindet, kann derselbe Import in verschiedene Binärdateien auf verschiedenen Geräten aufgelöst werden:
| Gerät |
api-win-core-samplefeature Karten zu |
|---|---|
| Ein Gerät, das das Feature enthält | samplefeature.dll |
| Ein Gerät, das eine umgestaltete Implementierung enthält | samplefeaturecore.dll |
| Ein Gerät, das das Feature nicht enthält | Nicht zugeordnet |
Die samplefeature hier verwendeten Namen sind illustrative Namen für eine fiktive Windows Komponente.
Die verbrauchende Binärdatei weiß nicht, an welchen Host sie gebunden war. Das ist der Punkt des Mechanismus: Der Vertrag ist stabil, während das Modul, das es implementiert, frei ist, von einem Gerät zum nächsten zu wechseln.
Ein Import eines Vertragsnamens wird in einem einzigen Vorgang aufgelöst, ohne dass ein Zwischenweiterleitungsmodul beteiligt ist. Es ist das effizienteste Formular und der normale Pfad für Code, der für API-Sätze geschrieben wurde.
API-Setnamen und das .dll Suffix
Da die Zuordnungen nicht auf dem Datenträger, sondern im Schema gespeichert werden, verweist ein API-Satzname, der mit .dll endet, nicht auf eine Datei dieses Namens. Der .dll Teil ist nur eine Benennungskonvention, die aus der Art und Weise übertragen wird, wie Modulnamen in einer Importtabelle geschrieben werden. Der NAME des API-Satzes ähnelt einem Alias oder einem virtuellen Namen für eine physische DLL-Datei.
Wenn ein Ladevorgang einen Namen empfängt, der mit api- oder ext-oder, leitet das Ladeprogramm ihn an die LAUFZEIT des API-Satzes weiter, eine Erweiterung des Ladeprogramms, mit dem Verträge über das Schema aufgelöst werden. Der API-Satz analysiert den Namen nach API-Set-Benennungsregeln und nicht als Dateinamen, sodass das .dll Suffix nicht Teil des Vertragsnamens ist, der aufgelöst wird. Schließen Sie das Suffix ein, wenn Sie mit einem Namen arbeiten, wie es in einer Importtabelle angezeigt wird. andernfalls können Sie es verlassen.
Das Ladeprogramm löst beide Formen des Vertragsnamens, einen versionsierten Vertragsnamen und einen Vertragsalias über dasselbe Schema auf. Informationen zu den Konventionen, die diese Namen regeln, finden Sie unter API-Set-Vertragsnamen.
Die Namensstabilität entspricht nicht der Verfügbarkeit.
Ein API-Satzname ist auf Windows Geräten stabil, sodass derselbe Name immer denselben Vertrag identifiziert, wo er erkannt wird. Dies ist eine Eigenschaft des Namespaces, keine Garantie für ein bestimmtes Gerät.
Ein bestimmter Vertrag kann von einem Gerät nicht vorhanden oder vorhanden, aber nicht einem Host zugeordnet sein. Nichts über den Namen teilt Ihnen mit, welches. Informationen dazu, ob die Implementierung tatsächlich vorhanden ist, finden Sie unter Erkennen der Verfügbarkeit von API-Sätze.
Welche Auflösung erforderlich ist
Für einen Aufruf über einen API-Satz, um eine Implementierung zu erreichen, müssen alle folgenden Elemente enthalten sein:
- Der Vertrag ist im Schema auf dem aktuellen Gerät vorhanden.
- Das Schema ordnet den Vertrag einer Host-Binärdatei zu, und dieser Host kann geladen werden.
- Der Host exportiert die spezifische Funktion, die ihre Binärdatei aufruft.
Wenn einer dieser Elemente nicht enthalten ist, hängt die Fehleroberfläche davon ab, wie Sie den API-Satz importiert haben:
| Formatvorlage importieren | Verhalten, wenn der Vertrag nicht aufgelöst werden kann |
|---|---|
| Statischer Import | Der Prozess kann nicht gestartet werden. Das Ladeprogramm löst statische Importe auf, bevor ein Code ausgeführt wird. |
| Verzögerter Import | Der Vorgang beginnt normal. Die Lösung wird auf den ersten Aufruf der API zurückgestellt, in dem Ihr Code den Fehler behandeln kann. |
Ein fehlender Export wird getrennt von einem fehlenden Vertrag gemeldet; Eine Binärdatei, die eine Funktion importiert, die vom Host nicht exportiert wird, schlägt mit einem fehlenden Einstiegspunktfehler fehl.
Was bei einer erfolgreichen Last nicht angezeigt wird
Die Lösung bindet einen Vertrag an einen Host. Er wertet den Status einer einzelnen Funktion innerhalb dieses Vertrags nicht aus.
Ein Vertrag kann seine individuell verfügbaren Funktionen in benannte Gruppen organisieren. Eine Gruppe kann auf einem Gerät nicht verfügbar sein, obwohl der Vertrag, der ihn enthält, normal aufgelöst wird, da das Ladeprogramm bei der Vertrags granularität bindet und den Gruppenstatus beim Binden nicht konsultiert. Das ist bewusst: Das Ablehnen der Bindung eines Hosts ist für einen statischen Import tödlich, sodass das Ladeprogramm den eingeschränkten Pfad übernimmt und die feinere Frage dem Aufrufer hinterlässt.
Die Folge für Den Code ist, dass ein erfolgreicher Ladevorgang oder ein erfolgreicher LoadLibrary-Aufruf kein Beweis dafür ist, dass eine bestimmte Funktion verfügbar ist. Stellen Sie diese Frage explizit mit einer Verfügbarkeitsabfrage. Siehe Erkennen der VERFÜGBARKEIT von API-Sätze.
Optionale API-Sätze und Verzögerung beim Laden
Wenn Ihre Anwendung einen API-Satz aufruft, der möglicherweise nicht vorhanden ist, reicht eine Verfügbarkeitsprüfung allein nicht aus: Bei einem statischen Import kann der Prozess nicht gestartet werden, sodass die Ausführung nie die Überprüfung erreicht.
Um den optionalen Codepfad erreichbar zu halten, konfigurieren Sie entweder das Modul, das die optionale API zum Verzögern des Ladens trägt, oder lösen Sie das Ziel dynamisch mit LoadLibrary und GetProcAddress auf, nachdem eine Verfügbarkeitsabfrage erfolgreich war. Details zu beiden Ansätzen finden Sie unter Erkennen der VERFÜGBARKEIT von API-Sätze.
Umgekehrte Weiterleitung
Während API-Setnamen einen stabilen Namespace für Module auf allen Geräten bereitstellen, ist es nicht immer praktisch, jede Binärdatei in dieses System zu konvertieren. Eine Anwendung ist möglicherweise seit vielen Jahren üblich, und die Neukompilierung der Binärdateien ist möglicherweise nicht machbar. Einige Anwendungen müssen auch weiterhin auf Systemen ausgeführt werden, die erstellt wurden, bevor bestimmte API-Sätze eingeführt wurden.
Um dies zu berücksichtigen, enthalten Editionen, die die ursprünglichen Module nicht enthalten, eine Reihe von Reverse-Weiterleitungen: Kompatibilitätsbinärdateien, die die modulnamen enthalten, die ursprünglich auf Windows-PCs eingeführt wurden, und die ihre Exporte an API-Sätze umleiten.
Eine vollständige Desktopedition enthält die ursprünglichen Module, sodass ein Import eines Legacymodulnamens an das Modul gebunden wird, wie es immer ist. Bei einer Edition, die dieses Modul ersetzt hat, deckt die umgekehrte Weiterleitung mit demselben Namen die Lücke ab.
Der Ladevorgang verhält sich wie folgt:
- Das Ladeprogramm wird mit einer Abhängigkeit von einem älteren Windows PC-Modulnamen angezeigt, der auf dem Gerät nicht vorhanden ist.
- Das Ladeprogramm sucht eine umgekehrte Weiterleitung, die diesen Modulnamen enthält, und lädt ihn.
- Die umgekehrte Weiterleitung leitet die importierte Funktion an einen API-Satz um.
- Das Ladeprogramm löst diese API, die über das Schema festgelegt wurde, wie weiter oben in diesem Thema beschrieben.
Konzeptionell sieht die Zuordnung wie folgt aus:
Importierte DLL: samplefeature.dll
- Auf einer Edition mit dem ursprünglichen Modul: samplefeature.dll
- In einer Edition, die sie ersetzt hat: samplefeature.dll Umgekehrte Weiterleitung ->samplefeaturecore.dll
api-win-core-samplefeature>
Der Grenzwert für diesen Pfad ist die Exportabdeckung. Eine Reverse-Weiterleitung führt nur die Exporte mit API-Satzäquivalenten, sodass nicht unbedingt jede Funktion exportiert wird, die das ursprüngliche Modul ausgeführt hat. Eine Binärdatei, die eine Funktion importiert, die die Reverseweiterleitung nicht enthält, kann nicht mit einem fehlenden Einstiegspunktfehler geladen werden.
Die Reverseweiterleitung ist auch ein Grund, eine erfolgreiche Lösung nicht als Beweis dafür zu behandeln, dass eine Implementierung vorhanden ist. Ein GetProcAddress-Aufruf mit einem Legacymodulnamen kann einen gültigen Funktionszeiger zurückgeben, der zu einem Stub aufgelöst wird, der einen Fehler zurückgibt. Die Verfügbarkeit von Abfragen wird stattdessen explizit verwendet. Siehe Erkennen der VERFÜGBARKEIT von API-Sätze.
Anmerkung
Die Reverseweiterleitung deckt nur eine Teilmenge der Win32-API-Oberfläche ab. Anwendungen, die auf Desktopversionen von Windows abzielen, können nicht auf allen Windows Geräten ausgeführt werden. Wenn Ihre binär auf aktuelle Versionen von Windows ausgerichtet ist, ist der NAME des API-Satzes-Vertrags die direktere Wahl.