Verwenden von dllimport und dllexport in C++-Klassen
Microsoft-spezifisch
Sie können C++-Klassen mit dem dllimport
Oder dllexport
Attribut deklarieren. Hierbei ist impliziert, dass die gesamte Klasse importiert oder exportiert wird. Klassen, die auf diese Weise exportiert werden, werden als exportierbare Klassen bezeichnet.
Im folgenden Beispiel wird eine exportierbare Klasse definiert. All ihre Memberfunktionen und statischen Daten werden exportiert:
#define DllExport __declspec( dllexport )
class DllExport C {
int i;
virtual int func( void ) { return 1; }
};
Beachten Sie, dass die explizite Verwendung der Attribute und dllexport
der dllimport
Elemente einer exportierbaren Klasse verboten ist.
dllexport Classes
Wenn Sie eine Klasse dllexport
deklarieren, werden alle Memberfunktionen und statische Datenmember exportiert. Sie müssen die Definitionen all dieser Member im gleichen Programm bereitstellen. Andernfalls wird ein Linkerfehler generiert. Die einzige Ausnahme dieser Regel gilt für rein virtuelle Funktionen, für die keine expliziten Definitionen bereitgestellt werden müssen. Da jedoch ein Destruktor für eine abstrakte Klasse immer vom Destruktor für die Basisklasse aufgerufen wird, müssen rein virtuelle Destruktoren immer eine Definition bereitstellen. Beachten Sie, dass diese Regeln auch für nicht exportierbare Klassen gelten.
Wenn Sie Daten vom Klassentyp oder Funktionen, die Klassen zurückgeben, exportieren, stellen Sie sicher, dass Sie die Klasse exportieren.
dllimport Classes
Wenn Sie eine Klasse dllimport
deklarieren, werden alle Memberfunktionen und statische Datenmember importiert. Im Gegensatz zum Verhalten von dllimport
und dllexport
für Nichtklassentypen können statische Datenmember keine Definition im selben Programm angeben, in dem eine dllimport
Klasse definiert ist.
Vererbung und exportierbare Klassen
Alle Basisklassen einer exportierbaren Klasse müssen exportierbar sein. Wenn dies nicht der Fall ist, wird eine Compilerwarnung ausgegeben. Darüber hinaus müssen alle zugreifbaren Member, die auch Klassen sind, exportierbar sein. Diese Regel ermöglicht es einer dllexport
Klasse, von einer dllimport
Klasse zu erben, und eine dllimport
Klasse, die von einer dllexport
Klasse erbt (dies wird jedoch nicht empfohlen). In der Regel sollte alles, auf das der DLL-Client zugreifen kann (gemäß C++-Zugriffsregeln), Teil der exportierbaren Schnittstelle sein. Hierzu zählen die privaten Datenmember, auf die in Inlinefunktionen verwiesen wird.
Selektiver Elementimport/-export
Da Memberfunktionen und statische Daten innerhalb einer Klasse implizit über externe Verknüpfungen verfügen, können Sie sie mit dem Attribut oder dem dllimport
Attribut dllexport
deklarieren, es sei denn, die gesamte Klasse wird exportiert. Wenn die gesamte Klasse importiert oder exportiert wird, ist die explizite Deklaration von Memberfunktionen und -daten unzulässig dllimport
dllexport
. Wenn Sie einen statischen Datenmemm innerhalb einer Klassendefinition als dllexport
deklarieren, muss eine Definition an einer beliebigen Stelle innerhalb desselben Programms (wie bei einer externen Verknüpfung ohne Klasse) auftreten.
Ebenso können Sie Memberfunktionen mit den dllimport
Attributen deklarieren dllexport
. In diesem Fall müssen Sie eine Definition an einer dllexport
beliebigen Stelle innerhalb desselben Programms angeben.
Es wird empfohlen, einige wichtige Aspekte hinsichtlich des selektiven Memberimports und -exports zu beachten:
Der selektive Memberimport und -export wird am besten zum Bereitstellen einer Version der exportierten Klassenschnittstelle verwendet, die restriktiver ist, also eine Schnittstelle, für die Sie eine DLL entwerfen können, die weniger öffentliche und private Funktionen verfügbar macht, als die Programmiersprache andernfalls zulassen würde. Er ist auch zum Optimieren der exportierbaren Schnittstelle nützlich: Wenn Sie wissen, dass der Client definitionsgemäß nicht in der Lage ist, auf einige private Daten zuzugreifen, müssen Sie nicht die gesamte Klasse exportieren.
Wenn Sie eine virtuelle Funktion in einer Klasse exportieren, müssen Sie alle exportieren, oder Sie müssen zumindest Versionen bereitstellen, die der Client direkt verwenden kann.
Wenn Sie über eine Klasse verfügen, in der Sie selektiven Memberimport und -export mit virtuellen Funktionen verwenden, müssen die Funktionen in der exportierbaren Schnittstelle auftreten oder inline definiert (für den Client sichtbar) sein.
Wenn Sie ein Element definieren,
dllexport
aber nicht in die Klassendefinition einschließen, wird ein Compilerfehler generiert. Sie müssen den Member im Header der Klasse definieren.Obwohl die Definition der Klassenmber als
dllimport
zulässigdllexport
ist, können Sie die in der Klassendefinition angegebene Schnittstelle nicht außer Kraft setzen.Wenn Sie eine Memberfunktion an einer anderen Stelle als dem Textkörper der Klassendefinition definieren, in der Sie sie deklariert haben, wird eine Warnung generiert, wenn die Funktion definiert
dllexport
ist oderdllimport
(wenn sich diese Definition von der in der Klassendeklaration angegebenen unterscheidet).
Ende Microsoft-spezifisch
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für