TN011: Verwenden von MFC in einer DLL

Diese Applikationsschrift beschreibt reguläre DLLs, die Ihnen erlauben, die MFC-Bibliothek als Teil einer Windows Dynamic Link Library (DLL) verwenden. Es wird davon ausgegangen, dass Sie mit Windows-DLLs und wie man sie baut vertraut sind. Informationen über MFC-Erweiterungs-DLLs, die Erweiterungen für die MFC-Bibliothek erstellen können, finden Sie unter DLL Version of MFC.

DLL-Schnittstellen

Reguläre DLLs übernehmen Schnittstellen zwischen der Anwendung und die DLL in normalen C-ähnlichen Funktionen oder explizit exportierten Klassen angegeben werden. MFC-Klassenschnittstellen können nicht exportiert werden.

Wenn eine DLL und eine Anwendung MFC verwenden möchten, dann haben beide die Wahl zwischen entweder verwenden die gemeinsam genutzte Version der MFC-Bibliotheken oder haben eine Kopie der MFC-Bibliothek statisch hinein. In Versionen vor Visual C++ 4.0 wurden die MFC-static Link Libraries für Anwendungen und DLLs. Mit der aktuellen Version von MFC, die Anwendung und die DLL können sowohl eines der standard-Versionen der MFC-Bibliothek verwenden. Es ist keine separate Bibliothek für DLLs, die in dieser Version (MFC macht die Wahl zur Laufzeit).

Reguläre DLLs verfügen mehrere Vorteile:

API-Einschränkungen

Einige MFC-Funktionen sind nicht anwendbar auf die DLL-Version, entweder aufgrund von technischen Einschränkungen oder weil diese Dienste in der Regel von der Anwendung bereitgestellt werden. Diese Einschränkungen werden nachfolgend aufgeführt.:

Erstellen der DLL

Beim Kompilieren von regulären DLLs, die statisch mit MFC verknüpfen, müssen die Symbole "_USRDLL" und "_WINDLL" definiert werden. Mit den folgenden Compilerschalter muss auch Ihre DLL-Code kompiliert werden:

Beim Kompilieren von regulären DLLs, die dynamisch mit MFC verknüpft die oben genannten Symbole definieren Sie und verwenden Sie die oben genannten Compilerschalter. Additonally, das Symbol "_AFXDLL" muss definiert werden, und Ihre DLL-Code kompiliert werden muss:

Die Schnittstellen (APIs) zwischen der Anwendung und die DLL müssen explizit exportiert werden. Es wird empfohlen, dass Sie Ihre Schnittstellen zu niedrige Bandbreite, definieren C Schnittstellen an, wo möglich. Direktere C Schnittstellen sind einfacher zu verwalten als komplexe C++-Klassen.

Platzieren Sie Ihre APIs in einem separaten Header, der von C- und C++-Dateien (auf diese Weise wird nicht Sie Ihre DLL-Kunden für C++-Programmierer zu begrenzen) enthalten sein kann. Finden Sie den TRACEAPI-Header.H in der MFC Advanced Concepts-Probe DLLTRACE für ein Beispiel. Um Ihre Funktionen zu exportieren, geben Sie sie im EXPORTS -Abschnitt von der Moduldefinitionsdatei (.DEF) oder __declspec(dllexport) auf Ihre Funktionsdefinitionen enthalten. Verwenden Sie __declspec(dllimport) , importieren Sie diese Funktionen in der ausführbare client.

Am Anfang aller exportierten Funktionen in regulären DLLs, die dynamisch mit MFC den aktuellen Modulstatus festlegen, die für die DLL zu verknüpfen, müssen Sie das AFX_MANAGE_STATE -Makro hinzufügen. Dies erfolgt durch Hinzufügen der folgenden Codezeile auf den Anfang des aus der DLL exportierten Funktionen:

Nbsp; & nbsp;

AFX_MANAGE_STATE (AfxGetStaticModuleState ())

Nbsp; & nbsp;

WinMain - ≫ DllMain

Die MFC-Bibliothek definiert den standard Win32 DllMain -Einstiegspunkt, der Ihre CWinApp abgeleitete Objekt als bei einer normalen MFC-Anwendung initialisiert. Legen Sie alle DLL-spezifischen Initialisierungen in InitInstance -Memberfunktion als bei einer normalen MFC-Anwendung.

Beachten Sie, dass der CWinApp:: Run -Mechanismus nicht auf eine DLL gelten, da die Anwendung die Haupt-Meldungsverteilschleife besitzt. Wenn die DLL nicht modale Dialogfelder öffnet oder ein eigenes Hauptrahmenfenster hat, muss Haupt-Meldungsverteilschleife der Anwendung eine DLL exportierte Routine aufrufen, die CWinApp:: PreTranslateMessage aufruft.

Finden Sie das DLLTRACE-Beispiel für die Verwendung dieser Funktion.

Die ExitInstance -Memberfunktion von Ihrem CWinApp abgeleiteten Klasse, von der MFC aufgerufen wird bereitgestellte DllMain -Funktion bevor die DLL entladen wird.

Was zu tun ist, um es allen zu verbinden

Mit reguläre DLLs, die statisch mit MFC verknüpfen, müssen Sie die DLL mit dieser Bibliothek (NAFXCWD. verknüpfen.LIB oder NAFXCW.LIB) zusammen mit der Version für die C-Laufzeitbibliotheken genannt "LIBCMT.LIB'. Diese Bibliotheken sind vorkonfigurierte und können installiert werden, indem Sie diese angeben, wenn Sie Visual C++ Setup ausführen.

Beispiel-Code

Finden Sie das Beispielprogramm MFC Advanced Concepts DLLTRACE ein vollständiges Beispiel. Dazu gehören eine einfache DLL namens ' TRACER.DLL', dass die AFX Ablaufverfolgungsflags Dialogfeld (siehe technische Anmerkung 7) implementiert. Es hat auch eine einfache HELLO-Anwendung, die die DLL verwenden das Dialogfeld aufruft.

Mehrere interessante Sache zu beachten:

Der folgende Auszug aus TRACEAPI.H zeigt, was für eine API erforderlich ist, die in eine reguläre DLL, die statisch mit MFC verknüpft definiert ist:

# ifdef __cplusplus
Extern "C" {}
#endifnbsp; / * __cplusplus * /

Struct TracerData
{
    BOOL bEnabled;
    UI&NT flags;
};

BOOL weit exportieren PASCAL PromptTraceFlags (TracerData FAR * LpData);

# ifdef __cplusplus
}
# endif

In diesem Beispiel wird die Deklaration in einem Block 'Extern "C"}' für C++-Benutzer eingeschlossen. Dies hat mehrere Vorteile. Zuerst, macht es Ihre DLL-APIs verwendbaren von nicht-c++-Clientanwendungen. Zweitens verringert es DLL Aufwand, da C++ Namenszerlegung nicht auf den exportierten Namen angewendet wird. Schließlich erleichtert es explizit hinzu ein.DEF-Datei (zum Exportieren nach Ordnungszahl) ohne sich Sorgen über Namenszerlegung.

Alle API-Funktionen sind "Weit PASCAL exportieren". Obwohl nicht streng für Win32-DLLs erforderlich, sind diese Definitionen für einfache Rücken-Portierung auf 16-Bit-Windows gehalten. Die fernen, PASCALund EXPORT -Makros alle erweitern Sie nichts unter Win32.

Die von der API verwendeten Strukturen nicht von MFC-Klassen abgeleitet sind und sind vollständig in die API-Header definiert. Dies verringert die Komplexität der Schnittstelle zwischen der DLL und der Anwendung und wieder einmal macht die DLL von C-Programmen nutzbar.

Alle Daten Zeiger verwendet in der API sind explizite FAR -Zeiger. Wieder, FAR, ist nicht wirklich notwendig für Win32, aber ist nützlich, wenn Sie planen, den Code kompilieren für 16-Bit-Windows irgendwann in der Zukunft.

Technische Hinweise von &Nummer |nbsp; Technische Hinweise nach Kategorie

Index