INFORMAZIONI: Utilizzo di _declspec (dllimport) & _declspec(dllexport) in codice

Traduzione articoli Traduzione articoli
Identificativo articolo: 132044 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

In questa pagina

Sommario

In questo articolo integra le informazioni contenute nel seguente articolo della Microsoft Knowledge Base riportato di seguito:
107501INFORMAZIONI: __export sostituiti per __declspec in Visual c ++ a 32 bit
In questo articolo vengono discussi i vantaggi e la meccanismi di utilizzare _declspec (dllimport) e _declspec(dllexport) nell'applicazione.

Informazioni

L'edizione a 32 bit di Visual c ++ utilizza _declspec (dllimport) e _declspec(dllexport) per sostituire la parola chiave __export utilizzata in precedenza di Visual c ++ nelle versioni a 16 bit.

Non Ŕ necessario utilizzare _declspec (dllimport) per il codice per compilare correttamente, ma consente al compilatore di generare codice pi¨ efficiente. Il compilatore Ŕ in grado di generare codice migliore perchÚ certezza sapere se una funzione Ŕ presente in una DLL o non, in modo che il compilatore pu˛ generare codici che ignorare un livello di riferimento indiretto normalmente presente in una chiamata di funzione che ha superato un limite DLL.

Con la corretta DEF sezione EXPORTS del file, _declspec(dllexport) non Ŕ necessaria. _declspec(dllexport) Ŕ stata aggiunta per offrire un modo semplice per esportare le funzioni da un file exe o DLL senza l'utilizzo di un file DEF.

Nel resto di questo articolo fornisce una descrizione completa, piuttosto basso livello di questi problemi.

Il formato di Win32 Portable Executable Ŕ progettato per ridurre al minimo il numero di pagine che devono essere utilizzate per correggere importazioni. Per effettuare questa operazione, tutti gli indirizzi di importazione per qualsiasi programma inserisce in una posizione denominata la tabella indirizzi Importa. In questo modo il caricatore modificare solo una o due pagine quando l'accesso a queste importazioni.

Utilizzare _declspec (dllimport) per le chiamate di funzione

Nell'esempio di codice riportato di seguito, presupporre func1 sia una funzione che si trova in una DLL separata dal file exe contenente la funzione main().

Senza _declspec (dllimport), dato questo codice:
void main(void) {
    func1();
}
				
il compilatore genera codice che Ŕ simile al seguente:
call func1
				
e il linker traduce la chiamata in qualcosa di simile:
call 0x4000000         ; The address of 'func1'.
				
se ' ' func1 si trova in un'altra DLL, il linker non Ŕ possibile risolvere il problema direttamente poichÚ non quali l'indirizzo di 'func1'. Negli ambienti di 16 bit, il linker aggiunge questo indirizzo di codice a un elenco nel eseguibile in cui il caricatore sarebbe patch in fase di esecuzione con l'indirizzo corretto. In ambienti a 32 bit, il linker genera un thunk per il quale conoscere l'indirizzo. Il thunk Ŕ simile al seguente:
   0x40000000:    jmp DWORD PTR __imp_func1
				
qui __imp_func1 Ŕ l'indirizzo dello slot di func1 nella tabella di indirizzi di importazione del file exe di. Tutti gli indirizzi sono quindi noti al linker. Il caricatore ha solo di aggiornare la tabella IAT del file exe in fase di carico per tutto funzioni correttamente.

Pertanto, l'utilizzo _declspec (dllimport) Ŕ preferibile poichÚ Ŕ preferibile se il linker non genera un thunk se non Ŕ necessario. Thunk rendere il codice pi¨ grande (su sistemi RISC, Ŕ possibile utilizzare diverse istruzioni) e pu˛ peggiorare il prestazioni della cache. Se indicare al compilatore che la funzione trova in una DLL, per l'utente pu˛ generare una chiamata indiretta.

A questo punto il codice:
__declspec(dllimport) void func1(void);

void main(void) {
    func1();
}
				
genera questa istruzione:
call DWORD PTR __imp_func1
				
non thunk e nessuna istruzione jmp, il codice Ŕ pi¨ piccolo e veloce.

D'altra parte, per le chiamate di funzione all'interno di una DLL non si desidera utilizzare una chiamata indiretta. Si conosce giÓ indirizzo della funzione. Tempo e spazio sono necessari per caricare e memorizzare l'indirizzo della funzione prima di una chiamata indiretta, in modo che una chiamata diretta sia sempre pi¨ veloce e pi¨ piccoli. Si desidera solo utilizzare __declspec (dllimport) quando si chiamano le funzioni di DLL dall'esterno della DLL stessa. Non utilizzare __declspec (dllimport) sulle funzioni all'interno di una DLL quando si genera tale DLL.

Utilizzando _declspec(dllexport)

Microsoft ha introdotto __export nella versione del compilatore di 16 bit per consentire al compilatore di generare automaticamente i nomi di esportazione e inserirli in un file LIB. Quindi Ŕ possibile utilizzare questo file LIB come un file LIB statico per il collegamento a una DLL.

Microsoft ha aggiunto __declspec (dllexport) per continuare questa comoditÓ. Il suo scopo Ŕ per aggiungere la direttiva di esportazione del file oggetto in modo da non Ŕ necessario un file DEF.

Questa comoditÓ Ŕ pi¨ evidente quando si tenta di esportare decorati i nomi delle funzioni di c ++. Non alcuna specifica standard per la decorazione dei nomi, quindi il nome di una funzione esportata pu˛ essere modificato tra le diverse versioni del compilatore. Se si utilizza _declspec(dllexport), la ricompilazione della DLL e il file exe dipendenti Ŕ necessaria solo per tenere conto di eventuali modifiche delle convenzioni di denominazione.

Molte direttive di esportazione come numeri ordinali, NONAME e PRIVATE, l'opzione possono essere definite solo in un file DEF e non esiste un modo per specificare questi attributi senza un file DEF. L'utilizzo di _declspec(dllexport) oltre a utilizzare un file DEF, tuttavia, non causa errori di generazione.

Come riferimento, cercare il file di intestazione Win32 WINBASE.H. Che contiene esempi di utilizzo di __declspec (dllexport) e come __declspec (dllimport) preferito.

Utilizzo di _declspec(dllexport) e _declspec (dllimport) nei dati

In caso di dati, utilizzare _declspec (dllimport) Ŕ un articolo comoditÓ rimuove un livello di riferimento indiretto. Quando si importano dati da una DLL, Ŕ necessario passare attraverso la tabella IAT. In giorni Win32 prima _declspec (dllimport), in questo modo Ŕ necessario ricordarsi di eseguire un ulteriore livello di riferimento indiretto durante l'accesso ai dati esportati dalla DLL:
// project.h
#ifdef _DLL     // If accessing the data from inside the DLL
   ULONG ulDataInDll;

else            // If accessing the data from outside the DLL
   ULONG *ulDataInDll;
#endif
				
Ŕ quindi possibile esportare i dati nel file def:
// project.def
LIBRARY project
EXPORTS
    ulDataInDll   CONSTANT
				
e accedervi all'esterno della DLL:
if (*ulDataInDll == 0L) {
   // Do stuff here
}
				
quando si contrassegnano i dati come __declspec (dllimport), il compilatore genera automaticamente il codice di riferimento indiretto per l'utente. Non Ŕ necessario preoccuparsi la procedura descritta in precedenza. Come affermato in precedenza, non utilizzare la dichiarazione _declspec (dllimport) sui dati durante la generazione della DLL. Le funzioni nella DLL non utilizza la tabella di indirizzi di importazione per accedere all'oggetto dati. Di conseguenza, non sarÓ necessario il livello aggiuntivo di riferimento indiretto presente.

Per esportare i dati automaticamente dalla DLL, utilizzare questa dichiarazione:
__declspec(dllexport) ULONG ulDataInDLL;
				

Utilizzo di un file DEF

Se si sceglie di utilizzare __declspec (dllimport) con un file DEF, Ŕ necessario modificare il file DEF utilizzare DATA anzichÚ CONSTANT per ridurre la probabilitÓ che il codice errato, causerÓ un problema:
// project.def
LIBRARY project
EXPORTS
    ulDataInDll   DATA
				
il grafico seguente mostra perchÚ:
Keyword     Emits in the import lib     Exports
CONSTANT    __imp_ulDataInDll           ulDataInDll
            __ulDataInDll

DATA        __imp_ulDataInDll           ulDataInDll
				
con _declspec (dllimport) e di CONSTANT Elenca la versione __imp_ e il nome non decorato nella libreria di importazione DLL LIB creata per consentire il collegamento esplicito. Utilizza _declspec (dllimport) e DATA elencata solo la versione di __imp_ del nome.

Se si utilizza CONSTANT, uno dei seguenti costrutti di codice Ŕ possibile utilizzare per accedere la ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/ 
   if (ulDataInDll == 0L)   /*sample code fragment*/ 
				
- oppure -
ULONG *ulDataInDll;      /*prototype*/ 
if (*ulDataInDll == 0L)  /*sample code fragment*/ 
				
Se tuttavia si utilizza DATA nel file DEF, solo il codice compilato con la seguente definizione pu˛ accedere il variabile ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll;
if (ulDataInDll == 0L)   /*sample code fragment*/ 
				
utilizzo CONSTANT Ŕ pi¨ rischioso perchÚ se si dimentica di utilizzare il livello aggiuntivo di riferimento indiretto, Ŕ possibile accedere potenzialmente puntatore della tabella di indirizzi di importazione alla variabile, non alla variabile stessa. Questo tipo di problema pu˛ manifestarsi spesso come violazione di accesso perchÚ la tabella di indirizzi di importazione viene effettuata attualmente sola lettura dal compilatore e linker.

Il linker corrente e Visual c ++ generato un avviso se individua CONSTANT nel file DEF per questo caso. L'unico motivo valido per utilizzare CONSTANT Ŕ Ŕ Impossibile ricompilare un file oggetto in cui il file di intestazione non elenca dllimport nel prototipo.

Riferimenti

Visual c ++ documentazione in linea di fornire una notevole quantitÓ di documentazione sul dllimport e dllexport classe di archiviazione attributi. Il capitolo "Creazione di DLL per Win32" il riferimento di tecniche di programmazione quali "I dllexport e dllimport attributi" e gli argomenti "utilizzo dllimport e dllexport in c ++" nel capitolo "Modificatori specifici Microsoft" del riferimento al linguaggio c ++ e gli argomenti "Esportazione di simboli". Per un elenco completo argomenti correlati, consultare la documentazione in linea di "dllimport" o "dllexport".

Per ulteriori informazioni, vedere i seguenti articoli della Microsoft Knowledge Base:
90530Come esportare dati da una DLL o un'applicazione
107501INFORMAZIONI: __export sostituiti per __declspec in Visual c ++ a 32 bit

ProprietÓ

Identificativo articolo: 132044 - Ultima modifica: martedý 2 dicembre 2003 - Revisione: 2.0
Le informazioni in questo articolo si applicano a:
  • Microsoft Visual C++ 1.0 Professional Edition
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 2.1
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
Chiavi:á
kbmt kbcode kbcompiler kbinfo KB132044 KbMtit
Traduzione automatica articoli
Il presente articolo Ŕ stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non Ŕ sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, pi¨ o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non Ŕ la sua. Microsoft non Ŕ responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 132044
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.
Dichiarazione di non responsabilitÓ per articoli della Microsoft Knowledge Base su prodotti non pi¨ supportati
Questo articolo Ŕ stato scritto sui prodotti per cui Microsoft non offre pi¨ supporto. L?articolo, quindi, viene offerto ?cosý come Ŕ? e non verrÓ pi¨ aggiornato.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com