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 dllexportdeklarieren, 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 dllimportdeklarieren, 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 dllimportdllexport . Wenn Sie einen statischen Datenmemm innerhalb einer Klassendefinition als dllexportdeklarieren, 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ässig dllexport 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 oder dllimport (wenn sich diese Definition von der in der Klassendeklaration angegebenen unterscheidet).

Ende Microsoft-spezifisch

Siehe auch

dllexport, dllimport