TN011: Usar MFC como parte de un archivo DLL

Esta nota describe los archivos DLL de MFC estándar, que le permiten utilizar la biblioteca MFC como parte de la biblioteca de vínculos dinámicos de Windows (DLL). Se supone que está familiarizado con los archivos DLL de Windows y cómo compilarlos. Para obtener información sobre los archivos DLL de extensión MFC, con los que puede crear extensiones en la biblioteca MFC, vea DLL Version of MFC (Versión dll de MFC).

Interfaces de DLL

Los archivos DLL de MFC normales asumen que las interfaces entre la aplicación y el archivo DLL se especifican en funciones similares a C o clases exportadas explícitamente. Las interfaces de clase MFC no se pueden exportar.

Si tanto un archivo DLL como una aplicación quieren usar MFC, ambos tienen la opción de usar la versión compartida de las bibliotecas de MFC o vincular estáticamente a una copia de las bibliotecas. Tanto la aplicación como el archivo DLL pueden usar una de las versiones estándar de la biblioteca MFC.

los archivos DLL de MFC normales tienen varias ventajas:

  • La aplicación que usa el archivo DLL no tiene que usar MFC y no tiene que ser una aplicación de Visual C++.

  • Con archivos DLL de MFC normales que se vinculan estáticamente a MFC, el tamaño del archivo DLL depende solo de las rutinas de tiempo de ejecución de MFC y C que se usan y vinculan.

  • Con los archivos DLL de MFC normales que se vinculan dinámicamente a MFC, el ahorro en memoria del uso de la versión compartida de MFC puede ser significativo. Sin embargo, debe distribuir los archivos DLL compartidos, la<versión> de Mfc.dll y la<versión de Msvvcrt>.dll, con el archivo DLL.

  • El diseño de DLL es independiente de cómo se implementan las clases. El diseño de DLL solo exporta a las API que desee. Como resultado, si la implementación cambia, los archivos DLL de MFC normales siguen siendo válidos.

  • Con archivos DLL de MFC normales que se vinculan estáticamente a MFC, si tanto dll como aplicación usan MFC, no hay problemas con la aplicación que quiere una versión diferente de MFC que el archivo DLL o viceversa. Dado que la biblioteca MFC está vinculada estáticamente a cada ARCHIVO DLL o EXE, no hay ninguna pregunta sobre qué versión tiene.

Limitaciones de API

Algunas funcionalidades de MFC no se aplican a la versión dll, ya sea debido a limitaciones técnicas o porque la aplicación suele proporcionar esos servicios. Con la versión actual de MFC, la única función que no es aplicable es CWinApp::SetDialogBkColor.

Creando su DLL

Al compilar archivos DLL de MFC normales que se vinculan estáticamente a MFC, se deben definir los símbolos _USRDLL y _WINDLL. El código DLL también debe compilarse con los siguientes modificadores del compilador:

  • /D_WINDLL significa que la compilación es para un archivo DLL

  • /D_USRDLL especifica que va a compilar un archivo DLL de MFC normal

También debe definir estos símbolos y usar estos modificadores del compilador al compilar archivos DLL de MFC normales que se vinculan dinámicamente a MFC. Además, el símbolo _AFXDLL debe definirse y el código DLL debe compilarse con:

  • /D_AFXDLL especifica que va a crear un archivo DLL de MFC normal que se vincula dinámicamente a MFC

Las interfaces (API) entre la aplicación y el archivo DLL deben exportarse explícitamente. Se recomienda definir las interfaces para que sean de ancho de banda bajo y usar solo interfaces de C si es posible. Las interfaces directas de C son más fáciles de mantener que las clases de C++ más complejas.

Coloque las API en un encabezado independiente que los archivos C y C++ puedan incluir. Consulte el encabezado ScreenCap.h en el archivo DLLScreenCap de ejemplo de conceptos avanzados de MFC para obtener un ejemplo. Para exportar las funciones, escríbalas en la sección EXPORTS del archivo de definición de módulo (. DEF) o incluya __declspec(dllexport) en las definiciones de función. Use __declspec(dllimport) para importar estas funciones en el archivo ejecutable del cliente.

Debe agregar la macro AFX_MANAGE_STATE al principio de todas las funciones exportadas en archivos DLL de MFC estándar que se vinculan dinámicamente a MFC. Esta macro establece el estado del módulo actual en el del archivo DLL. Para usar esta macro, agregue la línea de código siguiente al principio de las funciones exportadas desde el archivo DLL:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

WinMain:> DllMain

La biblioteca MFC define el punto de entrada estándar DllMain de Win32 que inicializa el objeto derivado de CWinApp como en una aplicación MFC típica. Coloque todo el código de inicialización específico del archivo DLL en el método InitInstance, como en una aplicación MFC estándar.

Tenga en cuenta que el mecanismo CWinApp::Run no se aplica a un archivo DLL porque la aplicación es la propietaria del suministro de mensajes principal. Si el archivo DLL muestra cuadros de diálogo sin modo o tiene una ventana de marco principal propia, el suministro de mensajes principal de la aplicación deberá llamar a una rutina exportada por el archivo DLL que llame a CWinApp::PreTranslateMessage.

Consulte el ejemplo DLLScreenCap para su uso de esta función.

La función DllMain que proporciona MFC llamará al método CWinApp::ExitInstance de la clase que se deriva de antes de CWinApp que se descargue el archivo DLL.

Vinculación del archivo DLL

Con los archivos DLL de MFC normales que se vinculan estáticamente a MFC, debe vincular el archivo DLL con Jsonxcwd.lib o Jsonxcw.lib y con la versión de los entornos de ejecución de C denominados Libcmt.lib. Estas bibliotecas se compilan previamente y se pueden instalar especificando al ejecutar el programa de instalación de Visual C++.

Código de ejemplo

Consulte el programa de ejemplo de conceptos avanzados de MFC DLLScreenCap para obtener un ejemplo completo. Hay varias cosas interesantes que se deben tener en cuenta en este ejemplo:

  • Las marcas del compilador del archivo DLL y las de la aplicación son diferentes.

  • Líneas de vínculo y los archivos .DEF para el archivo DLL y los de la aplicación son diferentes.

  • La aplicación que usa el archivo DLL no tiene que estar en C++.

  • La interfaz entre la aplicación y el archivo DLL es una API que puede usar C o C++ y se exporta con DLLScreenCap.def.

En el ejemplo siguiente se muestra una API que se define en un archivo DLL de MFC normal que se vincula estáticamente a MFC. En este ejemplo, la declaración se incluye en un bloque extern "C" { } para los usuarios de C++. Esto presenta una serie de ventajas. En primer lugar, hace que las API dll se puedan usar mediante aplicaciones cliente que no son de C++. En segundo lugar, reduce la sobrecarga de DLL porque la administración de nombres de C++ no se aplicará al nombre exportado. Por último, facilita la adición explícita a . Archivo DEF (para exportar por ordinal) sin tener que preocuparse por la mangling de nombres.

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

struct TracerData
{
    BOOL bEnabled;
    UINT flags;
};

BOOL PromptTraceFlags(TracerData FAR* lpData);

#ifdef __cplusplus
}
#endif

Las estructuras usadas por la API no se derivan de las clases MFC y se definen en el encabezado de API. Esto reduce la complejidad de la interfaz entre el archivo DLL y la aplicación y hace que los programas C puedan usar el archivo DLL.

Consulte también

Notas técnicas por número
Notas técnicas por categoría