Regole generali e limitazioni

Specifici di Microsoft

  • Se si dichiara una funzione o un oggetto senza dllimport o dllexport l'attributo, la funzione o l'oggetto non viene considerato parte dell'interfaccia DLL.Di conseguenza, la definizione della funzione o dell'oggetto sia presente in tale modulo o in un altro modulo dello stesso programma.Per fare parte dell'oggetto funzione o dell'interfaccia DLL, è necessario dichiarare la definizione della funzione o dell'oggetto in un altro modulo come dllexport.In caso contrario, verrà generato un errore del linker viene generato.

    Se si dichiara una funzione o un oggetto con dllexport l'attributo, la relativa definizione deve trovarsi in un modulo dello stesso programma.In caso contrario, verrà generato un errore del linker viene generato.

  • Se un singolo modulo nel programma contiene entrambi dllimport e dllexport le dichiarazioni per lo stesso esecuzione o oggetto, dllexport l'attributo ha la precedenza su dllimport attributo.Tuttavia, un avviso del compilatore viene generato.Di seguito è riportato un esempio:

    __declspec( dllimport ) int i;
    __declspec( dllexport ) int i;   // Warning; inconsistent;
                                     // dllexport takes precedence.
    
  • In C++, è possibile inizializzare un puntatore ai dati locale dichiarata a livello globale o statica o con l'indirizzo di un oggetto dati dichiarato con dllimport attributo, che genera un errore in C#.Inoltre, è possibile inizializzare un puntatore a funzione locale statico con l'indirizzo di una funzione dichiarata con dllimport attributo.In C#, tale assegnazione imposta il puntatore all'indirizzo del thunk di importazione della DLL (uno stub di codice che trasferisce il controllo alla funzione) anziché l'indirizzo della funzione.In C++, imposta il puntatore all'indirizzo della funzione.Di seguito è riportato un esempio:

    __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++
    }
    

    Tuttavia, un programma che includa dllexport l'attributo nella dichiarazione di un oggetto deve fornire la definizione di tale oggetto in un punto qualsiasi del programma, è possibile inizializzare un puntatore a funzione statica globale o locale con l'indirizzo di un oggetto dllexport funzione.Analogamente, è possibile inizializzare un puntatore ai dati statici globali o locali con l'indirizzo di un oggetto dllexport oggetto dati.Ad esempio, il codice seguente non genera errori in c o 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
    }
    
  • A causa di una modifica nel comportamento introdurre in Visual C++ .NET per renderla di dllexport più coerente tra le normali classi e le specializzazioni di template di classe, se si applica dllexport in una classe normale con una classe base non è contrassegnata come dllexport, il compilatore genererà C4275.

    Il compilatore genera lo stesso avviso se la classe base è una specializzazione di template di classe.Per ovviare a questo problema, contrassegnare la classe base con dllexport.Il problema con una specializzazione di template di classe consente di posizionare __declspec (dllexport); non è consentito per contrassegnare il modello di classe.Al contrario, la creazione esplicita di un'istanza del modello della classe e contrassegnare la creazione di istanza esplicita con dllexport.Di seguito è riportato un esempio:

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

    Questa soluzione alternativa si verifica se l'argomento di modello è la classe di derivazione.Di seguito è riportato un esempio:

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

    Poiché si tratta di modello comune con i modelli, il compilatore modificava la semantica di dllexport quando viene applicato a una classe che contiene una o più classi base e quando uno o più delle classi di base è una specializzazione di template di classe.In questo caso, il compilatore in modo implicito viene applicata dllexport le specializzazioni dei modelli della classe.In Visual C++ .NET, un utente può eseguire le operazioni seguenti e non ricevere un avviso:

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

Vedere anche

Riferimenti

dllexport, dllimport