DLLHUSK, exemple : liaison dynamique de la bibliothèque MFC
Mise à jour : novembre 2007
L'exemple DLLHUSK lie dynamiquement la bibliothèque MFC à des applications et à des bibliothèques de liens dynamiques (DLL) personnalisées qui partagent le même code de bibliothèque de classes, ce qui réduit la quantité totale de mémoire requise par l'exécution de plusieurs applications.
La liaison dynamique aux MFC offre d'autres architectures d'application possibles dans lesquelles une partie de l'application est implémentée dans une DLL personnalisée et dans lesquelles l'application et la DLL personnalisée partagent la DLL MFC (Mfcxx.dll). Une DLL personnalisée qui partage la fonctionnalité d'infrastructure avec une application est appelée une DLL d'extension MFC.
Note de sécurité : |
---|
Cet exemple de code est fourni pour illustrer un concept et ne doit pas être utilisé dans des applications ou des sites Web, car il peut ne pas illustrer les pratiques de programmation les plus sûres. Microsoft n'assume aucune responsabilité pour tout dommage indirect ou consécutif en cas d'utilisation de l'exemple de code à des fins autres que celles prévues. |
Pour obtenir des exemples et des instructions d'installation :
Dans le menu ? (Aide) de Visual Studio, cliquez sur Exemples.
Pour plus d'informations, consultez Recherche des fichiers d'exemple.
La liste la plus récente et la plus complète d'exemples est disponible en ligne à partir de la page Visual Studio 2008 Samples.
Des exemples sont également disponibles sur le disque dur de votre ordinateur. Des exemples et un fichier Readme sont copiés par défaut dans un dossier sous \Program Files\Visual Studio 9.0\Samples\. Pour les éditions Express de Visual Studio, tous les exemples sont accessibles en ligne.
Génération et exécution de l'exemple
Pour générer et exécuter l'exemple DLLHUSK
Ouvrez la solution dllhusk.sln.
Dans le menu Générer, cliquez sur Générer.
Dans le menu Déboguer, cliquez sur Exécuter sans débogage.
La solution DLLHUSK génère l'application Dllhusk.exe et les deux DLL (TESTDLL1.DLL et TESTDLL2.DLL) auxquelles l'application est liée dynamiquement. DLLHUSK a besoin de MFCxx.DLL ou MFCxxD.DLL au moment de l'exécution. Ces DLL sont installées par défaut dans le dossier système de Windows.
DLL d'extension MFC de DLLHUSK
DLLHUSK illustre des DLL d'extension MFC avec des exportations de classes. Les classes C++ des DLL (Testdll1.dll et Testdll2.dll) sont exportées à l'aide de la macro AFX_EXT_CLASS. La première DLL d'extension MFC (TESTDLL1) est une DLL dans laquelle toutes les interfaces de classe C++ de la DLL personnalisée sont accessibles par l'infrastructure uniquement et non directement par l'application. La DLL personnalisée exporte uniquement des fonctions extern "C" vers l'application. Elle n'a pas besoin d'exporter les fonctions des classes dérivées de classes de l'infrastructure. Tous les appels en provenance de l'infrastructure vers des classes dérivées de la DLL personnalisée sont résolus par le biais du mécanisme de fonction virtuelle C++.
La seconde DLL d'extension MFC (TESTDLL2) est une DLL dans laquelle certaines interfaces de classe C++ de la DLL personnalisée sont exportées vers l'application qui y accède directement.
Testdll1.dll
Testdll1.dll fournit l'implémentation des classes de document et d'affichage de DLLHUSK pour les deux types de documents : TEXT et HELLO. Dllhusk.exe implémente la classe de fenêtre frame MDI et l'infrastructure implémente la classe de fenêtre enfant MDI (interface multidocument) (CMDIChildWnd). Deux objets de modèle de document établissent les associations entre CTextDoc, CMDIChildWnd et CEditView d'une part et entre CDummyDoc, CMDIChildWnd et CHelloView d'autre part. DLLHUSK montre donc que l'infrastructure peut coordonner les relations entre des objets définis par l'infrastructure même si les classes de ces objets sont implémentées dans l'application, la DLL (d'extension MFC) personnalisée et la DLL de l'infrastructure Mfcxx.dll.
TESTDLL1 appelle en réalité deux fois la fonction membre AddDocTemplate de l'objet application pour inscrire les deux objets de modèle de document. Ces appels ont lieu dans l'implémentation de la fonction InitTestDLL1 de TESTDLL1, seule fonction exportée par TESTDLL1. Cette fonction est déclarée avec extern "C", de sorte que l'application DLLHUSK peut l'appeler comme une fonction C autonome.
Le fichier d'en-tête Testdll1.h (ajouté comme #include par Dllhusk.cpp) comprend non seulement la déclaration de InitTestDLL1,, mais aussi les déclarations des classes de TESTDLL1. Dllhusk.cpp fait directement référence à la fonction InitTestDLL1 uniquement. Toutefois, DLLHUSK utilise indirectement les classes de document et d'affichage implémentées dans Testdll1.dll.
Testdll2.dll
Testdll2.dll fournit l'implémentation de la classe CListOutputFrame de DLLHUSK. Lorsque l'utilisateur choisit une commande de diagnostic à l'aide du menu contextuel, l'application crée un objet CListOutputFrame, puis envoie les messages de diagnostic à la fenêtre List Output en appelant CListOutputFrame::AddString.
Toutes les fonctions membres publiques de CListOutputFrame sont exportées dans le fichier Testdll2.def. L'exportation comprend non seulement AddString, mais aussi le constructeur et le destructeur publics de CListOutputFrame.
Il est plus difficile d'implémenter une DLL d'extension MFC qui exporte des fonctions membres de classe qu'une DLL qui exporte uniquement des fonctions C. Cela est dû en particulier au fait que vous devez ajouter manuellement au fichier .def de la DLL les fonctions exportées avec des noms C++ décorés. Une technique de réalisation de cette tâche est décrite dans la note technique 33.
Autres fonctionnalités de DLLHUSK
DLLHUSK illustre également les fonctionnalités suivantes :
Division des ressources d'une seule application en plusieurs fichiers .rc pouvant être modifié dans l'éditeur de ressources de Visual C++.
Utilisation de deux fonctions de diagnostic globales, AfxDoForAllClasses et AfxDoForAllObjects.
Énumération d'objets CDynLinkLibrary.
Mots clés
Cet exemple illustre l'utilisation des mots clés suivants :
AfxDoForAllClasses ; AfxDoForAllObjects ; AfxGetApp ; AfxGetResourceHandle ; AfxMessageBox ; AfxSetResourceHandle ; AfxThrowMemoryException ; CCmdUI::SetCheck ; CColorDialog::DoModal ; CColorDialog::GetColor ; CDC::DrawText ; CDC::SetBkColor ; CDC::SetTextColor ; CDialogBar::Create ; CDocTemplate::GetDocString ; CEditView::SerializeRaw ; CFrameWnd::LoadFrame ; CListBox::AddString ; CListBox::Create ; CListBox::GetCount ; CListBox::GetText ; CListBox::GetTextLen ; CListBox::ResetContent ; CListBox::SetCurSel ; CMDIChildWnd::Create ; CMenu::GetSubMenu ; CMenu::LoadMenu ; CMenu::TrackPopupMenu ; CObject::AssertValid ; CObject::Dump ; CObject::Serialize ; CStatusBar::Create ; CStatusBar::SetIndicators ; CToolBar::Create ; CToolBar::LoadBitmap ; CToolBar::SetButtons ; CView::OnDraw ; CWinApp::AddDocTemplate ; CWinApp::InitInstance ; CWinApp::LoadStdProfileSettings ; CWinApp::OnFileNew ; CWinApp::OpenDocumentFile ; CWnd::GetClientRect ; CWnd::GetCurrentMessage ; CWnd::GetFont ; CWnd::Invalidate ; CWnd::OnCreate ; CWnd::OnNcRButtonDown ; CWnd::OpenClipboard ; CWnd::SetFont ; CWnd::ShowWindow ; CWnd::UpdateWindow ; CloseClipboard ; EmptyClipboard ; GetModuleFileName ; GetSysColor ; GlobalAlloc ; GlobalLock ; LOWORD ; RGB ; SetClipboardData ; lstrlen ; wsprintf
Remarque : |
---|
Certains exemples, tels que celui-ci, n'ont pas été modifiés pour refléter les changements apportés aux Assistants, aux bibliothèques et au compilateur Visual C++, mais ils illustrent bien l'exécution de la tâche souhaitée. |