Ejemplo DLLHUSK: vincula dinámicamente la biblioteca MFC

Actualización: noviembre 2007

El ejemplo DLLHUSK vincula dinámicamente la biblioteca MFC a aplicaciones y bibliotecas de vínculos dinámicos (DLL) personalizadas que comparten el mismo código de biblioteca de clases, con lo que se reduce la cantidad de memoria necesaria para ejecutar varias aplicaciones.

La vinculación dinámica a MFC también ofrece otras arquitecturas de aplicación posibles en las que parte de la aplicación se implementa en un archivo DLL personalizado, y la aplicación y el archivo DLL personalizado comparten el archivo DLL de MFC (Mfcxx.dll). Un archivo DLL personalizado que comparte la funcionalidad del marco de trabajo con una aplicación se denomina archivo DLL de extensión MFC.

Nota de seguridad:

Este código de ejemplo se proporciona para ilustrar un concepto y no debe utilizarse en aplicaciones o sitios Web, ya que quizás no ilustre las prácticas de codificación más seguras. Microsoft no asume ninguna responsabilidad por daños incidentales o consecuentes en caso de que el código de ejemplo se utilice para propósitos distintos de aquellos para los que se concibió.

Para obtener ejemplos e instrucciones para su instalación:

  • En el menú Ayuda de Visual Studio, haga clic en Ejemplos.

    Para obtener más información, vea Localizar archivos de ejemplo.

  • La lista de ejemplos completa con la versión más reciente está disponible en línea en la página Visual Studio 2008 Samples.

  • También encontrará ejemplos en el disco duro de su equipo. De manera predeterminada, los ejemplos y el archivo Léame se copian en una carpeta bajo \Archivos de programa\Visual Studio 9.0\Samples\. Para las versiones Express de Visual Studio, todos los ejemplos están en línea.

Generar y ejecutar el ejemplo

Para generar y ejecutar el ejemplo DLLHUSK

  1. Abra la solución dllhusk.sln.

  2. En el menú Generar, haga clic en Generar.

  3. En el menú Depurar, haga clic en Iniciar sin depurar.

La solución DLLHUSK genera la aplicación Dllhusk.exe y los dos archivos DLL (TESTDLL1.DLL y TESTDLL2.DLL) a los que se vincula dinámicamente la aplicación. DLLHUSK requiere MFCxx.DLL o MFCxxD.DLL en tiempo de ejecución. Estos archivos DLL se instalan de manera predeterminada en el directorio del sistema Windows.

Archivos DLL de extensión MFC de DLLHUSK

DLLHUSK ilustra el uso de archivos DLL de extensión MFC con exportaciones de clase. Las clases de C++ de los archivos DLL (Testdll1.dll y Testdll2.dll) se exportan mediante la macro AFX_EXT_CLASS. El primer archivo DLL de extensión MFC (TESTDLL1) es un archivo en el que el acceso a todas las interfaces de clase de C++ del archivo DLL personalizado sólo se realiza desde el marco de trabajo, no directamente desde la aplicación. El archivo DLL personalizado sólo exporta funciones extern "C" a la aplicación. El archivo DLL personalizado no tiene que exportar estas funciones de clases derivadas de las clases del marco de trabajo. Todas las llamadas realizadas desde el marco de trabajo a las clases derivadas del archivo DLL personalizado se resuelven mediante el mecanismo de funciones virtuales de C++.

El segundo archivo DLL de extensión MFC (TESTDLL2) es un archivo en el que algunas interfaces de clase C++ del archivo DLL personalizado se exportan a la aplicación, que tiene acceso directo a las interfaces.

Testdll1.dll

Testdll1.dll proporciona la implementación de las clases de documento y vista de DLLHUSK para los dos tipos de documento: los de tipo TEXT y los de tipo HELLO. El archivo Dllhusk.exe implementa la clase de ventana de marco MDI y el marco de trabajo implementa la clase de ventana secundaria (CMDIChildWnd) de la interfaz de múltiples documentos (MDI). Dos objetos de plantilla de documento establecen las asociaciones entre CTextDoc, CMDIChildWnd y CEditView, y entre CDummyDoc, CMDIChildWnd y CHelloView. Por tanto, DLLHUSK ilustra la capacidad del marco de trabajo de coordinar las relaciones entre objetos que define, aunque las clases de estos objetos están implementadas en la aplicación, el archivo DLL personalizado (extensión MFC) y el archivo Mfcxx.dll del marco de trabajo.

En realidad, TESTDLL1 llama dos veces a la función miembro AddDocTemplate del objeto de la aplicación para registrar los dos objetos de plantilla de documento. Lo hace así en la implementación de la función InitTestDLL1 de TESTDLL1, que es la única función que exporta TESTDLL1. La función se declara con extern "C", de forma que la aplicación DLLHUSK pueda llamarla como una función escrita en C independiente.

El archivo de encabezado Testdll1.h (agregado mediante #include por Dllhusk.cpp) incluye no sólo la declaración de InitTestDLL1, sino también las declaraciones de las clases TESTDLL1. Dllhusk.cpp sólo hace referencia directa a la función InitTestDLL1. Sin embargo, DLLHUSK utiliza indirectamente las clases de documento y de vista implementadas en Testdll1.dll.

Testdll2.dll

Testdll2.dll proporciona la implementación de la clase CListOutputFrame de DLLHUSK. Cuando el usuario elige un comando de diagnóstico en el menú de acceso directo, la aplicación crea un objeto CListOutputFrame y después envía mensajes de diagnóstico a la ventana List Output al llamar a CListOutputFrame::AddString.

Todas las funciones miembro públicas de CListOutputFrame se exportan en el archivo Testdll2.def. Las exportaciones no incluyen sólo AddString, sino también el constructor y el destructor públicos de CListOutputFrame.

Es más difícil implementar un archivo DLL de extensión MFC que exporta funciones miembro de clase que un archivo DLL que sólo exporte funciones C. Esto se debe en particular a que es necesario agregar manualmente las exportaciones de funciones C++ con nombre representativo al archivo .def del archivo DLL. En la Nota técnica 33 se explica una técnica para hacerlo.

Características adicionales de DLLHUSK

DLLHUSK también ilustra:

  • La forma de dividir los recursos de una aplicación en varios archivos .rc, que pueden editarse en el editor de recursos de Visual C++.

  • El uso de dos funciones globales de diagnóstico, AfxDoForAllClasses y AfxDoForAllObjects.

  • La forma de enumerar objetos CDynLinkLibrary.

Palabras clave

En este ejemplo, se muestra el uso de las siguientes palabras clave:

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

Nota:

Algunos ejemplos, como éste, no se han modificado para reflejar los cambios en los asistentes, las bibliotecas y el compilador de Visual C++, pero, aun así, muestran cómo realizar la tarea deseada.

Vea también

Otros recursos

Ejemplos de MFC