Was bedeutet __declspec (dllimport) wirklich?

Antworten:

117

__declspecist ein Microsoft-spezifisches Attribut, mit dem Sie Informationen zur Speicherklasse angeben können.
(Nitpicker's Corner: Einige andere Compiler-Anbieter - z. B. GCC - unterstützen diese Spracherweiterung jetzt, um die Kompatibilität mit der installierten Codebasis zu gewährleisten, die für Microsoft-Compiler geschrieben wurde. Einige bieten sogar zusätzliche Speicherklassenattribute.)

Zwei dieser Speicherklassenattribute, die angegeben werden können, sind dllimportund dllexport. Diese zeigen dem Compiler an, dass eine Funktion oder ein Objekt aus einer DLL importiert bzw. exportiert wird.

Insbesondere definieren sie die Schnittstelle der DLL zum Client, ohne dass eine module-definition ( .DEF) -Datei erforderlich ist . Die meisten Leute finden es viel einfacher, diese Spracherweiterungen zu verwenden, als DEF-Dateien zu erstellen.

Aus offensichtlichen Gründen __declspec(dllimport)und __declspec(dllexport)sind in der Regel miteinander gepaart. Sie dllexportmarkieren ein Symbol als aus einer DLL exportiert und dllimportimportieren dieses exportierte Symbol in eine andere Datei.

Aus diesem Grund und weil im Allgemeinen dieselbe Header-Datei sowohl beim Kompilieren der DLL als auch im Client-Code verwendet wird, der die DLL-Schnittstelle verwendet, ist es ein gängiges Muster, ein Makro zu definieren, das beim Kompilieren automatisch in den entsprechenden Attributbezeichner aufgelöst wird. Beispielsweise:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

Markieren Sie dann alle Symbole, mit denen exportiert werden soll DLLEXPORT.

Vermutlich ist es das, was das Q_CORE_EXPORTMakro tut, indem es entweder Q_DECL_IMPORToder auflöst Q_DECL_EXPORT.

Cody Grey
quelle
__declspec ist nicht richtig "MS-spezifisch" (es ist viel "compilerspezifischer") und einige Compiler verwenden diese Deklaration auch für mehrere Plattformen. Einige der Attributwerte sind (dllexport / dllimports sind tatsächlich MS-spezifisch, da DLL MS ist Lexikon).
Emilio Garavaglia
9
@Emilio: Soweit mir bekannt ist, hat Microsoft die __declspecNotation als Erweiterung der C ++ - Sprache erfunden . Ich glaube, dass GCC es jetzt unterstützt, aber das ist hauptsächlich aus Kompatibilitätsgründen mit den Compilern von Microsoft. Und ich verstehe nicht, wie sich "MS-spezifisch" von "Compiler-spezifisch" unterscheidet. Microsoft hat einen C ++ - Compiler geschrieben, den viele Benutzer verwenden. Es kommt mit Visual Studio.
Cody Gray
7
Microsoft macht einen Compiler. Es heißt "Microsoft C / C ++ Optimizing Compiler", cl.exe. Viele Leute verweisen fälschlicherweise auf Visual Studio, als wäre es ein Compiler, aber es ist eine IDE. Ich weiß nicht, warum die Leute nicht genau wissen, was "Microsoft-spezifisch" bedeutet. Es bedeutet nicht "MS-Umgebung" (was auch immer das ist), und es bedeutet sicherlich nicht "Windows". Ja, andere Compilerhersteller unterstützen jetzt die Erweiterung, um die Kompatibilität mit der installierten Codebasis zu gewährleisten, die für Microsoft-Compiler geschrieben wurde. Wie ich bereits sagte, hat Microsoft meines Wissens die Syntax erfunden. Darum geht es hier.
Cody Gray
2
@CodyGray: Microsoft allein erfunden zu haben, würde nicht ausreichen. Allerdings erfunden Microsoft hat es kein Standard enthält es, andere nur für die Kompatibilität der Implementierung und es in erster Linie verwendet wird (wenn auch nicht ausschließlich) für Programme Targeting Microsoft Windows zusammen einen sehr starken Punkt machen nennt es „Microsoft spezifische“
celtschk
6
Dies ist eine großartige Antwort, insbesondere der Teil über "weil im Allgemeinen dieselbe Header-Datei sowohl beim Kompilieren der DLL als auch im Client-Code verwendet wird"! Macht jeden Aspekt des Import / Export-Materials kristallklar.
Ela782
30

__declspec(dllimport) ist ein Speicherklassenspezifizierer, der dem Compiler mitteilt, dass eine Funktion, ein Objekt oder ein Datentyp in einer externen DLL definiert ist.

Die Funktion oder das Objekt oder der Datentyp wird aus einer DLL mit einer entsprechenden exportiert __declspec(dllexport).

arx
quelle
6
OK. Schließlich fand ich nach 2 Stunden Lesen die befriedigendste, prägnanteste und genaueste Aussage darüber, was ich will.
El Psy Congroo
1

__declspec(dllexport)Weist den Compiler an, den Linker darüber zu informieren, dass diese Symbole in die Exporttabelle eingefügt werden müssen (beim Kompilieren der DLL). Weist __declspec(dllimport)den Compiler beim Kompilieren des Programms, das mit der DLL verknüpft ist, an, einen Rip-relativen absoluten Register-indirekten indirekten Aufruf (den der Linker mit der Auflösung ausfüllt, um auf die Importtabelle zu verweisen) anstelle des üblichen Rip-relativen Registers direkt aufzurufenIndirekter Aufruf einer undefinierten Funktion (die den Befehl nicht ändern kann, fügt der Linker die relative Adresse eines Thunks ein und erstellt dann den Thunk, in dem er den rip-relativen absoluten Register-indirekten indirekten Aufruf an den platziert Funktionszeiger in der Importtabelle). Dies ist eine Optimierung der Codegröße und Geschwindigkeit. Es ist die .lib der Importbibliothek, die dem Linker mitteilt, welche Symbole importiert werden, und die als Leitfaden zum Erstellen der Importtabelle und zum Erstellen aller erforderlichen Thunks im .text-Segment verwendet wird.

https://docs.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://docs.microsoft.com/en-us/cpp / build / importing-data-using-declspec-dllimport? view = vs-2019 https://stackoverflow.com/a/4490536/7194773

Lewis Kelsey
quelle
-2

Dies bedeutet, dass sich die Definition der Funktion in einer dynamischen Bibliothek befindet. Weitere Details und Beispiele finden Sie in der Dokumentation .

Armen Tsirunyan
quelle