TN011: Usando MFC come parte di una DLL

Questa nota descrive le DLL regolari, che ti permettono di utilizzare la libreria MFC come parte di una libreria a collegamento dinamico (DLL) Windows. Esso presuppone che si abbia familiarità con le dll di Windows e come compilarli. Per informazioni sull'estensione MFC dll, che consentono di creare estensioni alla libreria MFC, vedere Versione DLL di MFC.

Interfacce DLL

DLL regolari si supponga interfacce tra l'applicazione e la DLL vengono specificate in normali funzioni di tipo c o classi esportate in modo esplicito. Interfacce di classi MFC non possono essere esportate.

Se una DLL o un'applicazione desidera utilizzare MFC, entrambi hanno una scelta di utilizzare la versione condivisa delle librerie MFC oppure avere una copia della libreria MFC collegata in modo statico in loro. Nelle versioni precedenti alla 4.0 di Visual C++, le librerie a collegamento statico MFC erano diverse per le applicazioni e le dll. Con la versione corrente di MFC, l'applicazione e la DLL possono entrambi utilizzano una delle versioni standard della libreria MFC. Non c'è una libreria separata per le dll in questa versione (MFC rende la scelta in fase di esecuzione).

DLL regolari presentano numerosi vantaggi:

Limitazioni di API

Alcune funzionalità MFC non sono applicabili alla versione DLL, sia a causa di limitazioni tecniche, o perché tali servizi sono di solito forniti dall'applicazione. Queste limitazioni sono elencate di seguito:

Costruendo la DLL

Quando si compila DLL regolari collegamento statico a MFC, i simboli "USRDLL" e "_WINDLL" deve essere definiti. Il codice della DLL deve essere compilato anche con le seguenti opzioni del compilatore:

Quando si compila un collegamento dinamico a MFC DLL regolari, è necessario definire i simboli di cui sopra e utilizzare le opzioni del compilatore sopra. Inoltre, deve essere definito il simbolo "AFXDLL" e deve essere compilato il codice DLL con:

Le interfacce (API) tra l'applicazione e la DLL devono essere esportate in modo esplicito. È consigliabile definire le interfacce ad essere bassa larghezza di banda, aderiscano alle interfacce c ove possibile. Interfacce c più dirette sono più facili da mantenere di classi C++ più complesse.

Posizionare le API in un'intestazione distinta che può essere inclusi i file sia c e C++ (in questo modo è non limitare i clienti DLL per i programmatori C++). Vedere l'intestazione TRACEAPI.H nell'esempio MFC Advanced Concepts DLLTRACE per un esempio. Per esportare le funzioni, entrare nella sezione EXPORTS del file di definizione del modulo (.DEF) o includere __declspec(dllexport) sulla vostra definizione di funzione. Utilizzare declspec per importare queste funzioni in client eseguibile.

All'inizio di tutte le funzioni esportate un collegamento dinamico a MFC per impostare lo stato corrente del modulo a quella per la DLL DLL regolari, è necessario aggiungere la macro AFX_MANAGE_STATE . Questo è fatto aggiungendo la seguente riga di codice all'inizio delle funzioni esportate dalla DLL:

nbsp; & nbsp;

AFX_MANAGE_STATE (AfxGetStaticModuleState ())

nbsp; & nbsp;

WinMain - > DllMain

La libreria MFC definisce il punto di ingresso di Win32 DllMain standard che inizializza l'oggetto derivata CWinApp come in una normale applicazione MFC. Inserire tutti i inizializzazione specifico della DLL nella funzione membro InitInstance come in una normale applicazione MFC.

Si noti che il meccanismo di CWinApp::Run non si applica a una DLL, dal momento che l'applicazione possiede il message pump principale. Se la DLL visualizza finestre di dialogo non modali o ha una propria finestra cornice principale, il message pump principale della vostra applicazione deve chiamare una routine esportata da DLL che chiama CWinApp:: PreTranslateMessage.

Vedere l'esempio DLLTRACE per l'utilizzo di questa funzione.

La funzione di membro di ExitInstance della CWinApp verrà chiamata classe derivata dal MFC fornito la funzione DllMain prima che la DLL venga scaricata.

Cosa fare per collegarlo tutti insieme

Con DLL regolari collegamento statico a MFC, è necessario collegare la DLL con questa libreria (NAFXCWD.LIB o NAFXCW.LIB) insieme con la versione dei runtime c chiamati ' LIBCMT.LIB'. Queste librerie sono pre-costruite e possono essere installate specificandoli quando si esegue l'installazione di Visual C++.

Codice di esempio

Si prega di vedere l'esempio di programma MFC Advanced Concepts DLLTRACE per un esempio completo. Questo include una semplice DLL denominata ' TRACER.DLL' che implementa il flag di traccia AFX di dialogo (vedi tecnica nota 7). Ha anche una semplice applicazione HELLO che chiama la DLL per utilizzare la finestra di dialogo.

Diversi cosa interessante da notare:

L'estratto seguente TRACEAPI.H illustra ciò che è necessario per una API definita in una DLL regolare che collega in modo statico a MFC:

# ifdef   Cplusplus
extern "C" {
#endifnbsp; / *   Cplusplus * /

struct TracerData
{
    BOOL bEnabled;
    UI&NT bandiere;
};

BOOL lontano esportare PASCAL PromptTraceFlags (estremo TracerData * lpData);

# ifdef   Cplusplus
}
# endif

In questo esempio, la dichiarazione è racchiuso in un blocco "extern"C"{}" per gli utenti di C++. Questo ha diversi vantaggi. In primo luogo, esso rende le API DLL utilizzabile dalle applicazioni client non C++. In secondo luogo, riduce l'overhead DLL poiché C++ alterazione dei nomi non verranno applicate al nome esportato. Infine, si rende più facile aggiungere in modo esplicito a una.DEF file (per l'esportazione di numero ordinale) senza doversi preoccupare di alterazione dei nomi.

Tutte le funzioni API sono "Molto PASCAL EXPORT". Anche se non strettamente necessari per le dll Win32, queste definizioni sono state tenute per facile porting di schiena a 16-bit Windows. Le macro estremo, PASCALed esportare tutti espandono a nulla sotto Win32.

Le strutture utilizzate dall'API non sono derivate dalle classi MFC e sono completamente definite nell'intestazione di API. Questo riduce la complessità dell'interfaccia tra la DLL e l'applicazione e, ancora una volta, rende la DLL utilizzabile tramite programmi c pure.

Eventuali puntatori di dati utilizzati nell'API sono espliciti estremo puntatori. Ancora una volta, estremo, non è davvero necessario per Win32, ma è utile se si prevede di compilare il codice per Windows a 16 bit in futuro.

&Note tecniche per numero |nbsp; Note tecniche per la categoria

Index