EXPORTS
Führt einen Abschnitt mit mindestens einer Exportdefinition ein, die die exportierten Namen oder Ordinalzahlen von Funktionen oder Daten angibt. Jede Definition muss sich in einer separaten Zeile befinden.
EXPORTS
definition
Hinweise
Die erste Definition kann sich in derselben Zeile wie das EXPORTS
Schlüsselwort oder in einer nachfolgenden Zeile befinden. Die .DEF-Datei kann eine oder mehrere EXPORTS
-Anweisungen enthalten.
Die Syntax für eine Exportdefinition lautet:
entryname[=internal_name other_module.exports|_name] [@Ordinal [NONAME] ] [ [PRIVATE] | [DATEN] ]
entryname is the function or variable name that you want to export. Diese Angabe ist obligatorisch. Wenn sich der Exportname vom Namen in der DLL unterscheidet, geben Sie den Namen des Exports in der DLL mithilfe von internal_name an. Wenn Ihre DLL beispielsweise eine Funktion func1
exportiert und Sie möchten, dass Aufrufer sie als func2
verwenden, würden Sie Folgendes angeben:
EXPORTS
func2=func1
Wenn der Name, den Sie exportieren, aus einem anderen Modul stammt, geben Sie den Namen des Exports in der DLL mithilfe von other_module.exports_name an. Wenn Ihre DLL beispielsweise eine Funktion other_module.func1
exportiert und Sie möchten, dass Aufrufer sie als func2
verwenden, würden Sie Folgendes angeben:
EXPORTS
func2=other_module.func1
Wenn der Name, den Sie exportieren, aus einem anderen Modul stammt, das nach Ordinal exportiert wird, geben Sie die Ordnungszahl des Exports in der DLL mithilfe von other_module an.#Ordnungszahl. Wenn Ihre DLL beispielsweise eine Funktion aus dem anderen Modul exportiert, in dem es sich um Ordinal 42 handelt, und Sie möchten, dass Aufrufer sie verwenden, wie func2
folgt:
EXPORTS
func2=other_module.#42
Da der MSVC-Compiler namens decoration für C++-Funktionen verwendet, müssen Sie entweder den verzierten Namen internal_name verwenden oder die exportierten Funktionen mithilfe extern "C"
des Quellcodes definieren. Der Compiler schmückt auch C-Funktionen, die die __stdcall Aufrufkonvention mit einem Unterstrichpräfix (_) und einem Suffix verwenden, das aus dem At-Zeichen (@) besteht, gefolgt von der Anzahl der Bytes (im Dezimalzeichen) in der Argumentliste.
Verwenden Sie das DUMPBIN-Tool oder die Linker /MAP-Option , um die vom Compiler erstellten versehenen Namen zu finden. Die ergänzten Namen sind compilerspezifisch. Wenn Sie die ergänzten Namen in der .DEF-Datei exportieren, müssen die ausführbaren Dateien, die zur DLL verknüpfen, ebenfalls mit derselben Version des Compilers erstellt werden. Damit wird sichergestellt, dass die ergänzten Namen im Aufrufer den exportierten Namen in der .DEF-Datei entsprechen.
Sie können @ordinal verwenden, um anzugeben, dass eine Zahl und nicht der Funktionsname in die Exporttabelle der DLL wechselt. Viele Windows-DLLs exportieren Ordinalzahlen, um Legacycode zu unterstützen. Es war üblich, Ordinalzahlen in 16-Bit-Windows-Code zu verwenden, weil das dazu beitragen kann, die Größe einer DLL zu minimieren. Es wird nicht empfohlen, Funktionen nach Ordnungszahl zu exportieren, es sei denn, die Clients ihrer DLL benötigen sie für die Legacyunterstützung. Da die .LIB-Datei die Zuordnung zwischen der Ordinalzahl und der Funktion enthält, können Sie den Funktionsnamen verwenden, wie Sie es normalerweise in Projekten tun würden, die die DLL verwenden.
Mithilfe des optionalen NONAME-Schlüsselworts können Sie nur nach Ordinal exportieren und die Größe der Exporttabelle in der resultierenden DLL verringern. Wenn Sie getProcAddress jedoch für die DLL verwenden möchten, müssen Sie das Ordnungszeichen kennen, da der Name ungültig ist.
Das optionale Schlüsselwort PRIVATE verhindert, dass der Eintragsname in die von LINK generierte Importbibliothek aufgenommen wird. Es wirkt sich nicht auf den Export des ebenfalls von LINK generierten Image aus.
Das optionale Schlüsselwort DATA gibt an, dass es sich bei einem Export um Daten handelt, nicht um Code. Das folgende Beispiel zeigt, wie Sie eine Datenvariable namens exported_global
exportieren könnten:
EXPORTS
exported_global DATA
Es gibt vier Möglichkeiten für das Exportieren einer Definition, aufgelistet in empfohlener Reihenfolge:
Das Schlüsselwort __declspec(dllexport) im Quellcode
Eine
EXPORTS
-Anweisung in einer .DEF-DateiEine /EXPORT-Spezifikation in einem LINK-Befehl
Eine Kommentardirektive im Quellcode des Formulars
#pragma comment(linker, "/export: definition ")
. Das folgende Beispiel zeigt eine #pragma Kommentardirektive vor einer Funktionsdeklaration, wobeiPlainFuncName
der nicht bewertete Name_PlainFuncName@4
und der versehene Name der Funktion ist:#pragma comment(linker, "/export:PlainFuncName=_PlainFuncName@4") BOOL CALLBACK PlainFuncName( Things * lpParams)
Die #pragma Direktive ist nützlich, wenn Sie einen nicht wirtschaftlichen Funktionsnamen exportieren müssen und je nach Buildkonfiguration unterschiedliche Exporte aufweisen (z. B. in 32-Bit- oder 64-Bit-Builds).
Alle vier Methoden können im selben Programm verwendet werden. Wenn LINK ein Programm erstellt, das Exporte enthält, wird auch eine Importbibliothek erstellt, es sei denn, im Build wird eine .EXP-Datei verwendet.
Hier ist ein Beispiel für einen EXPORTS-Abschnitt:
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllWindowName = WindowName DATA
DllGetClassObject @4 NONAME PRIVATE
DllRegisterServer @7
DllUnregisterServer
Wenn Sie eine Variable aus einer DLL über dien .DEF-Datei exportieren, müssen Sie __declspec(dllexport)
nicht in der Variable angeben. Sie müssen jedoch in jeder Datei, die die DLL verwendet, immer noch __declspec(dllimport)
in der Deklaration der Daten verwenden.