Freigeben über


Allgemeine Regeln und Einschränkungen

Microsoft-spezifisch

  • Wenn Sie eine Funktion oder ein Objekt ohne das dllimport oder dllexport-Attribut deklarieren, gilt die Funktion oder das Objekt nicht als Teil der DLL-Schnittstelle.Daher muss die Definition der Funktion oder des Objekts in diesem Modul oder in einem anderen Modul desselben Programms vorhanden sein.Um die Funktion oder den Teil Objekt aus der DLL-Schnittstelle zu machen, müssen Sie die Definition der Funktion oder des Objekts in einem anderen Modul als dllexportdeklarieren.Andernfalls wird ein Linkerfehler generiert.

    Wenn Sie eine Funktion oder ein Objekt mit dem dllexport-Attribut deklarieren, muss ihre Definition in einem Modul desselben Programms angezeigt werden.Andernfalls wird ein Linkerfehler generiert.

  • Wenn ein einzelnes Modul im Programm dllimport und dllexport Deklarationen für dieselbe Funktion oder - Objekt enthält, hat das dllexport-Attribut Vorrang vor dem dllimport-Attribut.Es wird eine Compilerwarnung ausgegeben.Beispiele:

    __declspec( dllimport ) int i;
    __declspec( dllexport ) int i;   // Warning; inconsistent;
                                     // dllexport takes precedence.
    
  • In C++ können Sie ein global deklariertes oder statisches lokales Datenzeiger oder die Adresse eines Datenobjekts initialisieren, das dem dllimport-Attribut deklariert wird, das einen Fehler in C generiert.Außerdem können Sie einen statischen lokalen Funktionszeiger mit der Adresse einer Funktion initialisieren, die mit dem dllimport-Attribut deklariert wird.In C legt eine solche Zuordnung den Zeiger auf die Adresse des DLL-Import thunks (ein Code zur Überträgt die Steuerung der stub Funktion) anstelle der Adresse der Funktion fest.In C++ wird der Zeiger auf die Adresse der Funktion fest.Beispiele:

    __declspec( dllimport ) void func1( void );
    __declspec( dllimport ) int i;
    
    int *pi = &i;                             // Error in C
    static void ( *pf )( void ) = &func1;     // Address of thunk in C,
                                              // function in C++
    
    void func2()
    {
       static int *pi = &i;                  // Error in C
       static void ( *pf )( void ) = &func1; // Address of thunk in C,
                                             // function in C++
    }
    

    Da ein Programm, das das dllexport-Attribut in der Deklaration eines Objekts enthält die Definition für dieses Objekt irgendwo im Programm bereitstellen muss, können Sie einen Zeiger der globale oder lokale statische Funktion mit der Adresse einer dllexport-Funktion initialisieren.Entsprechend können Sie auch einen Zeiger der globale oder lokale statische Daten mit der Adresse eines dllexport Datenobjekts initialisieren.Beispielsweise verursacht der folgende Code keine Fehler in C oder C++:

    __declspec( dllexport ) void func1( void );
    __declspec( dllexport ) int i;
    
    int *pi = &i;                              // Okay
    static void ( *pf )( void ) = &func1;      // Okay
    
    void func2()
    {
        static int *pi = &i;                   // Okay
        static void ( *pf )( void ) = &func1;  // Okay
    }
    
  • Aufgrund einer Änderung im Verhalten führen Sie in Visual C++ .NET ein, um die Anwendung von dllexport konsistenter zwischen regulären Klassen bereitstellen und Spezialisierungen von Klassenvorlagen, wenn Sie dllexport in einer normalen Klasse anwenden, die eine Basisklasse verfügt, die nicht als dllexportmarkiert ist, generiert der Compiler C4275.

    Der Compiler generiert die gleiche Warnung, wenn die Basisklasse über eine Spezialisierung einer Klassenvorlage ist.Um dies zu umgehen, markieren Sie die Basisklasse mit dllexport.Das Problem mit einer Spezialisierung einer Klassenvorlage ist, wo **__declspec (dllexport)**platziert. Sie sind nicht zulässig, um die Klassenvorlage zu markieren.Stattdessen, instanziieren Sie explizit die Klassenvorlage und markieren Sie diese explizite Instanziierung mit dllexport.Beispiele:

    template class __declspec(dllexport) B<int>;
    class __declspec(dllexport) D : public B<int> {
    // ...
    

    Diese Methode schlägt fehl, wenn das Vorlagenargument der abgeleiteten Klasse ist.Beispiele:

    class __declspec(dllexport) D : public B<D> {
    // ...
    

    Da dies allgemeines Muster mit Vorlagen, ist der Compiler die Semantik von dllexport , wenn er auf eine Klasse angewendet wird, die einen oder mehrere Basisklassen verfügt und wenn mindestens einer der Basisklassen eine Spezialisierung einer Klassenvorlage ist.In diesem Fall übernimmt der Compiler implizit dllexport auf Spezialisierungen von Klassenvorlagen.In Visual C++ .NET kann ein Benutzer wie folgt vorgehen und eine Warnung nicht abgerufen werden:

    class __declspec(dllexport) D : public B<D> {
    // ...
    

Siehe auch

Referenz

dllexport, dllimport