Verwenden von dllimport und dllexport in C++-Klassen

Microsoft-spezifisch

Sie können C++-Klassen mit dem dllimport oder dllexport dem 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 dllimportdllexport Attribute für Elemente einer exportierbaren Klasse verboten ist.

dllexport-Klassen

Wenn Sie eine Klasse dllexportdeklarieren, werden alle Memberfunktionen und statische Datenelemente 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-Klassen

Wenn Sie eine Klasse dllimportdeklarieren, werden alle Memberfunktionen und statische Datenelemente importiert. Im Gegensatz zum Verhalten und dllimportdllexport für nichtklassische Typen können statische Datenelemente keine Definition im gleichen 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. In dieser Regel kann eine dllexport Klasse von einer Klasse erben, und eine dllimport Klasse, die von einer dllimportdllexport Klasse erbt (obwohl dies nicht empfohlen wird). 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 Memberimport und -export

Da Memberfunktionen und statische Daten innerhalb einer Klasse implizit über externe Verknüpfungen verfügen, können Sie sie mit dem dllimport oder dllexport dem Attribut 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 als dllimport oder dllexport verboten. Wenn Sie ein statisches Datenelement innerhalb einer Klassendefinition als deklarieren, muss eine Definition dllexportirgendwo innerhalb desselben Programms auftreten (wie bei nichtklassischer externer Verknüpfung).

Ebenso können Sie Memberfunktionen mit den dllimportdllexport Attributen oder Attributen deklarieren. In diesem Fall müssen Sie eine dllexport Definition irgendwo in demselben Programm bereitstellen.

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 als dllexport element definieren, sie jedoch nicht in die Klassendefinition einschließen, wird ein Compilerfehler generiert. Sie müssen den Member im Header der Klasse definieren.

  • Obwohl die Definition von Klassenmitgliedern als dllimportdllexport zulässig ist, können Sie die in der Klassendefinition angegebene Schnittstelle nicht außer Kraft setzen.

  • Wenn Sie eine Memberfunktion an einem anderen Ort als dem Textkörper der Klassendefinition definieren, in der Sie es deklariert haben, wird eine Warnung generiert, wenn die Funktion definiert ist oder dllimport (wenn sich diese Definition von der in der Klassendeklaration angegebenen dllexport Unterscheidet).

Ende Microsoft-spezifisch

Siehe auch

dllexport, dllimport