Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Hinweis
Die Microsoft Foundation Classes (MFC)-Bibliothek wird weiterhin unterstützt. Wir fügen jedoch keine Features mehr hinzu oder aktualisieren die Dokumentation.
In diesem Hinweis werden reguläre MFC-DLLs beschrieben, mit denen Sie die MFC-Bibliothek als Teil einer Windows Dynamic Link Library (DLL) verwenden können. Es wird davon ausgegangen, dass Sie mit Windows-DLLs und deren Erstellung vertraut sind. Informationen zu MFC-Erweiterungs-DLLs, mit denen Sie Erweiterungen für die MFC-Bibliothek erstellen können, finden Sie unter DLL-Version von MFC.
DLL-Schnittstellen
Reguläre MFC-DLLs gehen davon aus, dass Schnittstellen zwischen der Anwendung und der DLL in C-ähnlichen Funktionen oder explizit exportierten Klassen angegeben werden. MFC-Klassenschnittstellen können nicht exportiert werden.
Wenn sowohl eine DLL als auch eine Anwendung MFC verwenden möchten, haben beide die Möglichkeit, entweder die freigegebene Version der MFC-Bibliotheken zu verwenden oder eine Statisch-Verknüpfung mit einer Kopie der Bibliotheken zu erstellen. Die Anwendung und DLL können beide eine der Standardversionen der MFC-Bibliothek verwenden.
reguläre MFC DLLs haben mehrere Vorteile:
Die Anwendung, die die DLL verwendet, muss MFC nicht verwenden und muss keine Visual Studio-Anwendung sein.
Bei regulären MFC-DLLs, die statisch mit MFC verknüpfen, hängt die Größe der DLL nur von den verwendeten und verknüpften MFC- und C-Laufzeitroutinen ab.
Bei regulären MFC-DLLs, die dynamisch mit MFC verknüpfen, kann die Speichereinsparung bei der Verwendung der gemeinsam genutzten MFC-Version erheblich sein. Sie müssen jedoch die freigegebenen DLLs, Mfc<version>.dll und Msvvcrt<version>.dll, mit Ihrer DLL verteilen.
Das DLL-Design ist unabhängig davon, wie Klassen implementiert werden. Ihr DLL-Design exportiert nur an die gewünschten APIs. Wenn sich die Implementierung ändert, sind reguläre MFC-DLLs weiterhin gültig.
Bei regulären MFC-DLLs, die statisch mit MFC verknüpfen, wenn sowohl DLL als auch Anwendung MFC verwenden, gibt es keine Probleme mit der Anwendung, die eine andere Version von MFC wünscht als die DLL oder umgekehrt. Da die MFC-Bibliothek statisch mit jeder DLL oder EXE verknüpft ist, gibt es keine Frage, welche Version Sie haben.
API-Einschränkungen
Einige MFC-Funktionen gelten nicht für die DLL-Version, entweder aufgrund technischer Einschränkungen oder weil diese Dienste in der Regel von der Anwendung bereitgestellt werden. Mit der aktuellen Version von MFC ist die einzige Funktion, die nicht anwendbar ist CWinApp::SetDialogBkColor.
Erstellen Ihrer DLL
Beim Kompilieren regulärer MFC-DLLs, die statisch mit MFC verknüpfen, müssen die Symbole _USRDLL_WINDLL definiert werden. Ihr DLL-Code muss auch mit den folgenden Compileroptionen kompiliert werden:
/D_WINDLL bedeutet, dass die Kompilierung für eine DLL gilt.
/D_USRDLL gibt an, dass Sie eine normale MFC-DLL erstellen.
Sie müssen diese Symbole auch definieren und diese Compileroptionen verwenden, wenn Sie reguläre MFC-DLLs kompilieren, die dynamisch mit MFC verknüpft werden. Darüber hinaus muss das Symbol _AFXDLL definiert sein, und Ihr DLL-Code muss mit folgendem Kompiliert werden:
- /D_AFXDLL gibt an, dass Sie eine normale MFC-DLL erstellen, die dynamisch mit MFC verknüpft wird.
Die Schnittstellen (APIs) zwischen der Anwendung und der DLL müssen explizit exportiert werden. Es wird empfohlen, dass Sie Ihre Schnittstellen mit geringer Bandbreite definieren und nur C-Schnittstellen verwenden, wenn möglich. Direct C-Schnittstellen sind einfacher zu verwalten als komplexere C++-Klassen.
Platzieren Sie Ihre APIs in einem separaten Header, der sowohl von C- als auch von C++-Dateien eingeschlossen werden kann. Ein Beispiel finden Sie im Header "ScreenCap.h" im Projektbeispiel für MFC Advanced Concepts DLLScreenCap. Um Ihre Funktionen zu exportieren, geben Sie sie in den EXPORTS Abschnitt Ihrer Moduldefinitionsdatei (.DEF) ein oder fügen Sie __declspec(dllexport) in Ihre Funktionsdefinitionen ein. Verwenden Sie __declspec(dllimport), um diese Funktionen in die ausführbare Clientdatei zu importieren.
Sie müssen das AFX_MANAGE_STATE Makro am Anfang aller exportierten Funktionen in regulären MFC-DLLs hinzufügen, die dynamisch mit MFC verknüpfen. Dieses Makro legt den aktuellen Modulstatus auf die 1 für die DLL fest. Um dieses Makro zu verwenden, fügen Sie die folgende Codezeile am Anfang der Funktionen hinzu, die aus der DLL exportiert wurden:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
WinMain -> DllMain
Die MFC-Bibliothek definiert den Win32-Standardeinstiegspunkt DllMain , der das von CWinApp abgeleitete Objekt wie in einer typischen MFC-Anwendung initialisiert. Platzieren Sie alle DLL-spezifischen Initialisierungen in der InitInstance-Methode wie in einer typischen MFC-Anwendung.
Beachten Sie, dass der CWinApp::Run-Mechanismus nicht auf eine DLL angewendet wird, da die Anwendung die Hauptnachrichtenpumpe besitzt. Wenn Ihre DLL nicht modale Dialoge anzeigt oder ein eigenes Frame-Hauptfenster besitzt, muss die Hauptnachrichtenpumpe Ihrer Anwendung eine von der DLL exportierte Funktion aufrufen, die CWinApp::PreTranslateMessage aufruft.
Weitere Informationen zur Verwendung dieser Funktion finden Sie im DLLScreenCap-Beispiel.
Die von MFC bereitgestellte Funktion ruft die Methode DllMain Ihrer Klasse auf, die von abgeleitet ist, bevor die DLL entladen wird.
Linken Ihrer DLL
Bei normalen MFC-DLLs, die statisch mit MFC gelinkt werden, müssen Sie Ihre DLL mit Nafxcwd.lib oder Nafxcw.lib und mit der Version der C-Laufzeiten namens Libcmt.lib linken. Diese Bibliotheken sind vorinstalliert und können installiert werden, indem sie beim Ausführen von Visual Studio-Setup angegeben werden.
Beispielcode
Ein abschließendes Beispiel finden Sie in dem MFC Advanced Concepts Beispielprogramm DLLScreenCap. Einige interessante Punkte, die Sie in diesem Beispiel beachten müssen, sind wie folgt:
Die Compilerflags der DLL und die der Anwendung unterscheiden sich.
Die Verknüpfungslinien und . DEF-Dateien für die DLL und diejenigen für die Anwendung sind unterschiedlich.
Die Anwendung, die die DLL verwendet, muss nicht in C++ enthalten sein.
Die Schnittstelle zwischen der Anwendung und der DLL ist eine API, die von C oder C++ verwendet werden kann und mit DLLScreenCap.def exportiert wird.
Das folgende Beispiel veranschaulicht eine API, die in einer regulären MFC-DLL definiert ist, die statisch mit MFC verknüpft ist. In diesem Beispiel wird die Deklaration in einen extern "C" { } Block für C++-Benutzer eingeschlossen. Dies hat mehrere Vorteile. Zunächst können Ihre DLL-APIs von Nicht-C++-Clientanwendungen verwendet werden. Zweitens wird der DLL-Aufwand reduziert, da C++-Namens-Mangling nicht auf den exportierten Namen angewendet wird. Schließlich erleichtert es das explizite Hinzufügen zu einer .DEF-Datei (für den Export nach Ordnungszahlen), ohne dass Sie sich um die Namensverwechslung kümmern müssen.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct TracerData
{
BOOL bEnabled;
UINT flags;
};
BOOL PromptTraceFlags(TracerData FAR* lpData);
#ifdef __cplusplus
}
#endif
Die von der API verwendeten Strukturen werden nicht von MFC-Klassen abgeleitet und werden im API-Header definiert. Dies reduziert die Komplexität der Schnittstelle zwischen der DLL und der Anwendung und macht die DLL von C-Programmen nutzbar.
Siehe auch
Technische Hinweise nach Nummer
Technische Hinweise nach Kategorie