Information: Verwenden von _declspec(dllimport) & _declspec(dllexport) in Code

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 132044 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

In diesem Artikel ergänzen die Informationen in der folgenden Artikel der Microsoft Knowledge Base behandelt:
107501INFO: __export durch __declspec in Visual C++ 32-Bit-ersetzt
Dieser Artikel beschreibt die vor- und Mechanismen der Verwendung von _declspec(dllimport) und _declspec(dllexport) in Ihrer Anwendung.

Weitere Informationen

32-Bit-Edition von Visual C++ wird _declspec(dllimport) und _declspec(dllexport) verwendet, um die __export Schlüsselwort, das zuvor in 16-Bit-Versionen von Visual C++ zu ersetzen.

Es müssen nicht _declspec(dllimport) für Ihren Code verwenden, um ordnungsgemäß zu kompilieren, bietet jedoch den Compiler, besseren Code zu generieren die Möglichkeit. Der Compiler kann besseren Code generieren, da Sie sicher weiß, ob eine Funktion in einer DLL oder nicht existiert, so dass der Compiler Codes erzeugen kann, die eine Dereferenzierungsebene überspringen, die normalerweise würde in einem Funktionsaufruf, der eine DLL-Grenze überschritten.

_Declspec(dllexport) ist mit dem richtigen DEF-Datei EXPORTS-Abschnitt nicht erforderlich. _declspec(dllexport) wurde hinzugefügt, um eine einfache Möglichkeit, Funktionen aus einer EXE- oder DLL zu exportieren, ohne Verwendung einer DEF-Datei zu gewährleisten.

Der Rest der dieser Artikel bietet eine ziemlich einfache, gründliche Beschreibung dieser Probleme.

Das portable ausführbare Win32-Format soll die Anzahl der Seiten minimieren, die berührt Imports behoben werden muss. Zu diesem Zweck wird die Import-Adressen für jedes Programm in einem Ort als die Importadressentabelle bezeichnet. Dies ermöglicht das Ladeprogramm an nur eine oder zwei Seiten ändern, wenn diese Importe zugreift.

Verwendung von _declspec(dllimport) für Funktionsaufrufe

Im folgenden Codebeispiel wird genommen Sie func1 ist eine Funktion, die sich in einer DLL getrennt von der EXE-Datei befindet, die die Main()-Funktion enthält an.

Ohne _declspec(dllimport), erhält dieses Codes:
void main(void) {
    func1();
}
				
generiert der Compiler Code, der wie folgt aussieht:
call func1
				
und der Linker übersetzt den Aufruf in etwa wie folgt:
call 0x4000000         ; The address of 'func1'.
				
Wenn 'func1' in einer anderen DLL vorhanden ist, der Linker kann nicht auflösen dieser direkt, da es keine Möglichkeit hat bekannt, welche die Adresse der 'func1' ist. In 16-Bit-Umgebungen fügt der Linker diese Adresse Code einer Liste in exe, die das Ladeprogramm zur Laufzeit mit der richtigen Adresse patch würde hinzu. In 32-Bit-Umgebungen generiert der Linker einen Thunk für den Sie die Adresse kennen. Der Thunk sieht folgendermaßen aus:
   0x40000000:    jmp DWORD PTR __imp_func1
				
__imp_func1 ist hier die Adresse des func1 Slot in der Importadressentabelle der EXE-Datei. Folglich sind dem Linker alle Adressen bekannt. Das Ladeprogramm muss nur aktualisieren, Importadressentabelle der EXE-Datei zur Ladezeit für alles richtig funktioniert.

Daher ist die Verwendung von _declspec(dllimport) besser, weil es besser, ist wenn der Linker keinen Thunk generiert, wenn auf nicht es. Thunks vergrößern den Code (auf RISC-Systemen, es kann sein mehrere Anweisungen) und die Cacheleistung beeinträchtigen können. Wenn Sie dem Compiler die Funktion in einer DLL ist, kann Sie einen indirekten Aufruf generieren.

Jetzt diesen Code:
__declspec(dllimport) void func1(void);

void main(void) {
    func1();
}
				
diese Anweisung generiert:
call DWORD PTR __imp_func1
				
es keinen Thunk und ist keine Jmp-Anweisung der Code kleiner und schneller ist.

Andererseits, möchten nicht für Funktionsaufrufe innerhalb einer DLL, Sie einen indirekten Aufruf verwenden müssen. Sie wissen bereits, Adresse einer Funktion. Zeit und Speicherplatz sind erforderlich zum Laden und speichern die Adresse der Funktion vor einem indirekten Aufruf, sodass ein direkter Aufruf immer schneller und kleinere ist. Nur __declspec(dllimport) verwendet werden soll beim Aufrufen von DLL-Funktionen von außerhalb der DLL selbst. __Declspec(dllimport) nicht für Funktionen innerhalb einer DLL verwendet werden, beim Erstellen dieser DLL.

Mithilfe von _declspec(dllexport)

Microsoft führte __export in der 16-Bit-Compilerversion, damit der Compiler die Namen exportieren automatisch generieren und platziert diese in einer LIB-Datei. Diese LIB-Datei konnte dann wie eine statische LIB verwendet werden, mit einer DLL verknüpfen.

Microsoft hinzugefügt __declspec(dllexport) dieser Vereinfachung fortfahren. Dient der Objektdatei die Export-Direktive hinzufügen, damit Sie eine DEF-Datei benötigen.

Dieses benutzerfreundliche ist augenfälligste, wenn C++-Funktionsnamen exportieren möchten ergänzten. Es gibt keine Standardspezifikation für die Namensergänzung, daher den Namen einer exportierten Funktion zwischen Compilerversionen ändern kann. Wenn Sie _declspec(dllexport) verwenden, ist die Neukompilierung der DLL und der abhängigen exe-Dateien für naming Convention Änderungen nur für Konto erforderlich.

Viele exportieren Direktiven, z. B. Ordinalzahlen, NONAME und PRIVATE, nur in einer DEF-Datei vorgenommen werden kann, und es keine Möglichkeit gibt, diese Attribute ohne DEF-Datei festzulegen. Mithilfe von _declspec(dllexport) zusätzlich zur Verwendung einer DEF-Datei führt jedoch nicht dazu, dass Buildfehler.

Ein Verweis der Win32-WINBASE.H-Headerdatei durchsuchen. Sie enthält Verwendungsbeispiele bevorzugte __declspec(dllexport) und als __declspec(dllimport).

Verwenden von _declspec(dllexport) und _declspec(dllimport) auf Daten

Im Fall von Daten bietet die Verwendung _declspec(dllimport) eine bequeme Möglichkeit, die eine Dereferenzierungsschicht entfernt. Wenn Sie Daten aus einer DLL importieren, müssen Sie noch die Importadressentabelle durchlaufen. In der Win32-Tage bevor _declspec(dllimport) Dies bedeutete mussten Sie eine zusätzliche Dereferenzierungsebene tun, wenn Zugriff auf Daten aus der DLL exportiert Denken Sie daran:
// project.h
#ifdef _DLL     // If accessing the data from inside the DLL
   ULONG ulDataInDll;

else            // If accessing the data from outside the DLL
   ULONG *ulDataInDll;
#endif
				
Sie würden die Daten dann in der DEF-Datei exportieren:
// project.def
LIBRARY project
EXPORTS
    ulDataInDll   CONSTANT
				
und außerhalb der DLL zugreifen:
if (*ulDataInDll == 0L) {
   // Do stuff here
}
				
Wenn Sie die Daten mit __declspec(dllimport) kennzeichnen, generiert der Compiler automatisch den Code Dereferenzierung für Sie. Sie müssen nicht mehr sorgen die oben genannten Schritte. Wie bereits erwähnt, verwenden Sie keine _declspec(dllimport) Deklaration auf die Daten beim Erstellen der DLL. Funktionen in der DLL werden nicht der Importadressentabelle für den Zugriff auf das Datenobjekt verwendet. Daher müssen Sie die zusätzliche Dereferenzierungsebene vorhanden nicht.

Um die Daten automatisch aus der DLL exportieren, verwenden diese Deklaration:
__declspec(dllexport) ULONG ulDataInDLL;
				

Verwenden einer DEF-Datei

Wenn Sie __declspec(dllimport) zusammen mit einer DEF-Datei verwenden, Sie sollten heben Sie den .DEF Daten anstelle von CONSTANT verwenden, um die Wahrscheinlichkeit verringern, dass falsche Codierung ein Problem führt:
// project.def
LIBRARY project
EXPORTS
    ulDataInDll   DATA
				
das folgende Diagramm zeigt die Gründe:
Keyword     Emits in the import lib     Exports
CONSTANT    __imp_ulDataInDll           ulDataInDll
            __ulDataInDll

DATA        __imp_ulDataInDll           ulDataInDll
				
mit _declspec (Dllimport) und CONSTANT werden sowohl die __imp_ Version und den nicht ergänzten Namen in der .LIB DLL importieren Bibliothek für das explizite Verknüpfen erstellten aufgeführt. Verwendung von _declspec(dllimport) und Daten werden nur die __imp_-Version den Namen aufgeführt.

Wenn Sie CONSTANT verwenden, kann eine der folgenden Codekonstrukte zum Zugriff auf die UlDataInDll verwendet werden:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/ 
   if (ulDataInDll == 0L)   /*sample code fragment*/ 
				
-oder-
ULONG *ulDataInDll;      /*prototype*/ 
if (*ulDataInDll == 0L)  /*sample code fragment*/ 
				
Wenn Sie Daten in der DEF-Datei verwenden, nur mit der folgenden Definition kompiliert Code kann allerdings zugreifen Variable UlDataInDll:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L)   /*sample code fragment*/ 
				
verwenden CONSTANT ist mehr riskant, da Sie vergessen, die zusätzliche Dereferenzierungsebene zu verwenden, Sie möglicherweise die Importadressentabelle Zeiger auf die Variable--nicht die Variable selbst zugreifen konnte. Diese Art von Problem kann häufig als eine Zugriffsverletzung Assemblymanifest, da die Importadressentabelle momentan schreibgeschützt durch den Microsoft-Compiler und Linker vorgenommen wird.

Der aktuelle Visual C++-Linker gibt eine Warnung, wenn Sie CONSTANT in der DEF-Datei für diesen Fall berücksichtigen. Der einzige wirkliche Grund CONSTANT verwenden ist, wenn Sie einige Objekt neu kompilieren nicht möglich, in denen die Headerdatei Dllimport für den Prototyp Liste nicht.

Informationsquellen

Der Visual C++ Onlinedokumentation liefern eine beträchtliche der Dokumentation zu dem Dllexport und Dllimport Speicherklasse Attribute. Dazu gehören "Die Dllexport und Dllimport-Attributen" und "mit Dllimport und Dllexport in C++" in den Themen im Kapitel "Microsoft-spezifische Modifizierer" der C++-Sprachreferenz in und in den Themen "Symbole exportieren" im Kapitel "Erstellen von DLLs für Win32" des Verweises Programming Verfahren. Verwandte Themen suchen der Onlinedokumentation für "Dllimport" oder "Dllexport", um eine gründliche Liste.

Weitere Informationen finden Sie in die folgenden Artikeln der Microsoft Knowledge Base:
90530Gewusst wie: Exportieren von Daten aus einer DLL oder einer Anwendung
107501INFO: __export durch __declspec in Visual C++ 32-Bit-ersetzt

Eigenschaften

Artikel-ID: 132044 - Geändert am: Dienstag, 2. Dezember 2003 - Version: 2.0
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft Visual C++ 1.0 Professional Edition
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 2.1
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
Keywords: 
kbmt kbcode kbcompiler kbinfo KB132044 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 132044
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.
Disclaimer zu nicht mehr gepflegten KB-Inhalten
Dieser Artikel wurde für Produkte verfasst, für die Microsoft keinen Support mehr anbietet. Der Artikel wird deshalb in der vorliegenden Form bereitgestellt und nicht mehr weiter aktualisiert.

Ihr Feedback an uns

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com