Regole e limitazioni per dllimport/dllexport

Specifico di Microsoft

  • Se si dichiara una funzione senza l'attributo dllimport o dllexport , la funzione non viene considerata parte dell'interfaccia DLL. Di conseguenza, la definizione della funzione deve essere presente in tale modulo o in un altro modulo dello stesso programma. Per rendere la funzione parte dell'interfaccia DLL, è necessario dichiararne la definizione nell'altro modulo come dllexport. In caso contrario, durante la compilazione del client verrà generato un errore del linker.

  • Se un singolo modulo nel programma contiene dllimport e dllexport dichiarazioni per la stessa funzione, l'attributo dllexport ha la precedenza sull'attributo dllimport . Viene tuttavia generato un avviso del compilatore. Ad esempio:

    #define DllImport   __declspec( dllimport )
    #define DllExport   __declspec( dllexport )
    
       DllImport void func1( void );
       DllExport void func1( void );   /* Warning; dllexport */
                                       /* takes precedence. */
    
    
  • Non è possibile inizializzare un puntatore dati statico con l'indirizzo di un oggetto dati dichiarato con l'attributo dllimport . Il codice seguente genera ad esempio errori:

    #define DllImport   __declspec( dllimport )
    #define DllExport   __declspec( dllexport )
    
       DllImport int i;
       .
       .
       .
       int *pi = &i;                           /* Error */
    
       void func2()
       {
          static int *pi = &i;                   /* Error */
       }
    
    
  • Inizializzazione di un puntatore a funzione statico con l'indirizzo di una funzione dichiarata con dllimport imposta il puntatore all'indirizzo dell'importazione DLL del thunk (uno stub di codice che trasferisce il controllo alla funzione) anziché l'indirizzo della funzione. Questa assegnazione non genera un messaggio di errore:

    #define DllImport   __declspec( dllimport )
    #define DllExport   __declspec( dllexport )
    
       DllImport void func1( void
       .
       .
       .
       static void ( *pf )( void ) = &func1;   /* No Error */
    
       void func2()
       {
          static void ( *pf )( void ) = &func1;  /* No Error */
       }
    
    
  • Poiché un programma che include l'attributo dllexport nella dichiarazione di un oggetto deve fornire la definizione di tale oggetto, è possibile inizializzare un puntatore a funzione statico globale o locale con l'indirizzo di una funzione dllexport. Analogamente, è possibile inizializzare un puntatore a dati statico globale o locale con l'indirizzo di un oggetto dati dllexport. Ad esempio:

    #define DllImport   __declspec( dllimport )
    #define DllExport   __declspec( dllexport )
    
       DllImport void func1( void );
       DllImport int i;
    
       DllExport void func1( void );
       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 */
       }
    
    

END Microsoft Specific

Vedi anche

Funzioni di importazione ed esportazione DLL