Exportar e importar mediante AFX_EXT_CLASS
Los archivos DLL de extensión utilizan la macro AFX_EXT_CLASS para exportar clases; los archivos ejecutables que se vinculan al archivo DLL de extensión utilizan la macro para importar clases. Con la macro AFX_EXT_CLASS, se puede utilizar los mismos archivos de encabezado que para generar el archivo DLL de extensión con los archivos ejecutables que se vinculan al archivo DLL.
En el archivo de encabezado para el archivo DLL debe agregar la palabra clave AFX_EXT_CLASS a la declaración de la clase de la manera siguiente:
class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};
MFC define esta macro como __declspec(dllexport) cuando se definen los símbolos de preprocesador _AFXDLL y _AFXEXT. Pero la macro se define como __declspec(dllimport) cuando _AFXDLL está definido y _AFXEXT no está definido. Cuando está definido, el símbolo de preprocesador _AFXDLL indica que el archivo ejecutable de destino (un archivo DLL o una aplicación) está utilizando la versión compartida de MFC. Si _AFXDLL y _AFXEXT están definidos, el archivo ejecutable de destino es un archivo DLL de extensión.
Como la macro AFX_EXT_CLASS está definida como __declspec(dllexport) al exportar desde un archivo DLL de extensión, se pueden exportar clases completas sin colocar los nombres representativos para todos los símbolos de la clase en el archivo .def. Este método se utiliza en el ejemplo DLLHUSK de MFC.
Aunque puede evitar la creación de un archivo .def y todos los nombres representativos para la clase con este método, la creación de un archivo .def es más eficaz, ya que se puede exportar los nombres por ordinal. Para utilizar el método de exportación del archivo .def, coloque el código siguiente al principio y al final del archivo de encabezado:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Precaución |
---|
Debe tener cuidado al exportar funciones inline, ya que podrían producir conflictos entre versiones. Una función inline se expande en el código de la aplicación; por tanto, si después vuelve a escribir la función, no se actualizará a menos que se vuelva a compilar la aplicación. Normalmente, las funciones de archivos DLL pueden actualizarse sin volver a generar las aplicaciones que las utilizan. |
Exportar miembros individuales de una clase
Puede que a veces le interese exportar miembros individuales de la clase. Por ejemplo, si va a exportar una clase derivada de CDialog, quizá sólo necesite exportar el constructor y la llamada a DoModal. Puede utilizar AFX_EXT_CLASS en los miembros individuales que desea exportar.
Por ejemplo:
class CExampleDialog : public CDialog
{
public:
AFX_EXT_CLASS CExampleDialog();
AFX_EXT_CLASS int DoModal();
...
// rest of class definition
...
};
Como ya no va a exportar todos los miembros de la clase, podría producirse un problema adicional por la manera en que funcionan las macros de MFC. Varias macros auxiliares de MFC sirven en realidad para declarar o definir miembros de datos. Por tanto, también deben exportarse estos miembros de datos desde el archivo DLL.
Por ejemplo, la macro DECLARE_DYNAMIC se define de la manera siguiente cuando se genera un archivo DLL de extensión:
#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
La línea que empieza por static AFX_DATA se declara como un objeto estático dentro de la clase. Para exportar correctamente esta clase y tener acceso a la información en tiempo ejecución desde un archivo ejecutable cliente, deberá exportar este objeto estático. Como el objeto estático se declara con el modificador AFX_DATA, sólo tendrá que definir AFX_DATA como __declspec(dllexport) al generar el archivo DLL y definirlo como __declspec(dllimport) al generar el archivo ejecutable cliente. Como la macro AFX_EXT_CLASS ya está definida de esta manera, sólo deberá volver a definir AFX_DATA como AFX_EXT_CLASS en torno a la definición de la clase.
Por ejemplo:
#undef AFX_DATA
#define AFX_DATA AFX_EXT_CLASS
class CExampleView : public CView
{
DECLARE_DYNAMIC()
// ... class definition ...
};
#undef AFX_DATA
#define AFX_DATA
MFC siempre utiliza el símbolo AFX_DATA en los elementos de datos que define dentro de las macros, por lo que esta técnica funcionará para todos estos escenarios. Por ejemplo, funcionará para DECLARE_MESSAGE_MAP.
Nota
Si va a exportar toda la clase en lugar de miembros seleccionados de la clase, se exportan automáticamente los miembros de datos estáticos.
¿Qué desea hacer?
Exportar funciones de C++ para utilizarlas en ejecutables en C
Exportar funciones de C para utilizarlas en ejecutables en C o C++