Condividi tramite


Utilizzo di dllimport e dllexport nelle classi C++

Sezione specifica Microsoft

È possibile dichiarare classi C++ con l'attributo dllimport o dllexport . Questi formati implicano l'importazione o l'esportazione dell'intera classe. Le classi esportate in questo modo vengono denominate classi esportabili.

Nell'esempio seguente viene definita la classe esportabile. Viene eseguita l'esportazione di tutte le relative funzioni membro e di tutti i dati statici:

#define DllExport   __declspec( dllexport )

class DllExport C {
   int i;
   virtual int func( void ) { return 1; }
};

Si noti che l'uso dllimport esplicito degli attributi e dllexport nei membri di una classe esportabile non è consentito.

Classi dllexport

Quando si dichiara una classe dllexport, vengono esportate tutte le relative funzioni membro e membri dati statici. È necessario fornire le definizioni di tutti i membri nello stesso programma. In caso contrario, viene generato un errore del linker. L'unica eccezione a questa regola viene applicata alle funzioni virtuali pure per le quali non è necessario fornire definizioni esplicite. Tuttavia, poiché un distruttore di una classe astratta viene sempre chiamato dal distruttore della classe base, i distruttori virtuali puri devono fornire sempre una definizione. Si noti che queste regole sono identiche per le classi non esportabili.

Se si esportano dati di tipo classe o funzioni che restituiscono classi, assicurarsi di esportare la classe.

Classi dllimport

Quando si dichiara una classe dllimport, vengono importate tutte le relative funzioni membro e membri dati statici. A differenza del comportamento di dllimport e dllexport su tipi non di classi, i membri dati statici non possono specificare una definizione nello stesso programma in cui viene definita una dllimport classe.

Ereditarietà ed esportazione di classi

Tutte le classi base di una classe esportabile devono essere esportabili. In caso contrario, viene generato un avviso del compilatore. Inoltre, tutti i membri accessibili che rappresentano classi devono essere esportabili. Questa regola consente a una dllexport classe di ereditare da una dllimport classe e a una dllimport classe di ereditare da una dllexport classe (anche se quest'ultima non è consigliata). Di norma, qualsiasi elemento accessibile al client della DLL (in base alle regole di accesso di C++) deve far parte dell'interfaccia esportabile. Sono inclusi i membri dati privati a cui viene fatto riferimento nelle funzioni inline.

Importazione/Esportazione membro selettivo

Poiché le funzioni membro e i dati statici all'interno di una classe hanno un collegamento esterno in modo implicito, è possibile dichiararli con l'attributo dllimport o dllexport , a meno che l'intera classe non venga esportata. Se l'intera classe viene importata o esportata, la dichiarazione esplicita di funzioni membro e dati come dllimport o dllexport è vietata. Se si dichiara un membro dati statico all'interno di una definizione di classe come dllexport, è necessario che una definizione si trovi all'interno dello stesso programma (come con il collegamento esterno non della classe).

Analogamente, è possibile dichiarare funzioni membro con gli dllimport attributi o dllexport . In questo caso, è necessario specificare una dllexport definizione all'interno dello stesso programma.

È opportuno notare diversi aspetti importanti relativi all'importazione e all'esportazione selettive dei membri:

  • L'importazione/esportazione selettiva dei membri è più adatta per fornire una versione dell'interfaccia della classe esportata più restrittiva, ovvero una per la quale è possibile progettare una DLL che esponga un numero inferiore di funzionalità pubbliche e private di quante ne consentirebbe il linguaggio. È inoltre utile per l'ottimizzazione dell'interfaccia esportabile: quando si sa che il client non è per definizione in grado di accedere ai dati privati, non è necessario esportare l'intera classe.

  • Se si esporta una funzione virtuale di una classe, è necessario esportarle tutte o fornire almeno le versioni che possono essere utilizzate direttamente dal client.

  • Se si dispone di una classe in cui si utilizza l'importazione o l'esportazione selettiva dei membri con le funzioni virtuali, tali funzioni devono trovarsi nell'interfaccia esportabile o essere definite inline (visibili al client).

  • Se si definisce un membro come dllexport ma non lo si include nella definizione della classe, viene generato un errore del compilatore. È necessario definire il membro nell'intestazione della classe.

  • Anche se la definizione dei membri della classe come dllimport o dllexport è consentita, non è possibile eseguire l'override dell'interfaccia specificata nella definizione della classe.

  • Se si definisce una funzione membro in una posizione diversa dal corpo della definizione di classe in cui è stata dichiarata, viene generato un avviso se la funzione è definita come dllexport o dllimport (se questa definizione è diversa da quella specificata nella dichiarazione di classe).

Fine sezione specifica Microsoft

Vedi anche

dllexport, dllimport