Exporting String Classes Using CStringT
En el pasado, los desarrolladores de MFC tienen derivado de CString especializar sus propias clases de la cadena. En Microsoft Visual C++ .NET (MFC 8,0), la clase de CString se sustituye por una clase de plantilla con CStringT. Esto proporciona varias ventajas:
Permitía que la clase MFC CString se usó en proyectos ATL sin vinculación en la biblioteca estática mayor o DLL de MFC.
Con la nueva clase de plantilla de CStringT , puede personalizar el comportamiento de CString mediante los parámetros de plantilla que especifican rasgos de carácter, similares a las plantillas en la biblioteca de (STL) plantillas estándar.
Cuando exporta posee la clase de cadena de un archivo DLL mediante CStringT, el compilador también se exporta automáticamente la clase base de CString . Puesto que CString es una clase de plantilla, se pueden crear instancias del compilador cuando se utiliza, a menos que el compilador tenga en cuenta que CString se importa de DLL. Si se ha migrado proyectos de Visual C++ 6,0 y Visual C++ .NET, es posible que haya visto los errores de símbolos del vinculador para CString multiplicar-definido debido a la colisión de CString importar desde un archivo DLL y la versión localmente crear instancias. La manera adecuada de ello se describe a continuación. Para obtener más información sobre este problema, vea el artículo de Knowledge Base, “vinculando errores cuando se importa clases CString-derivadas” (Q309801) en el CD-ROM de MSDN Library o en https://support.microsoft.com/default.aspx.
El escenario siguiente provocará el vinculador a errores de símbolos de producción para multiplica clases definidas. Suponga que exporte CString- clase derivada (CMyString) de un archivo DLL de extensión de MFC:
// MyString.h
class AFX_EXT_CLASS CMyString : public CString
{
// Your implementation code
};
El código del consumidor utiliza una combinación de CString y de CMyString. " MyString.h” no se incluye en el encabezado precompilado, y el uso de CString no tiene CMyString visible.
Suponga que utiliza las clases de CString y de CMyString en los archivos de código fuente independientes, Source1.cpp y Source2.cpp. En Source1.cpp, se utiliza CMyString y #include MyString.h. En Source2.cpp, se utiliza CString, pero no #include MyString.h. en este caso, el vinculador se quejará por CStringT que es multiplica definido. El está provocado por CString que se está importando de DLL que exporta CMyString, y creado instancias localmente por el compilador mediante la plantilla de CStringT .
Para resolver este problema, haga lo siguiente:
Exportar CStringA y CStringW (y clases base necesarias) MF C90 .DLL. Proyectos que incluyan MFC usarán siempre MFC CStringA exportado DLL y CStringW, como en las implementaciones anteriores de MFC.
A continuación cree una clase derivada exportable mediante la plantilla de CStringT , mientras que CStringT_Exported está presionada, por ejemplo:
#ifdef _AFXDLL
#define AFX_EXT_CSTRING AFX_EXT_CLASS
#else
#define AFX_EXT_CSTRING
#endif
template< typename BaseType, class StringTraits >
class AFX_EXT_CSTRING CStringT_Exported
: public CStringT< BaseType, StringTraits >
{
// Reimplement all CStringT<> constructors and
// forward to the base class implementation
};
En AfxStr.h, reemplace CStringanterior, CStringA, y tipos de CStringW como sigue:
typedef CStringT_Exported< wchar_t,
StrTraitMFC< wchar_t > > CStringW;
typedef CStringT_Exported< char,
StrTraitMFC< char > > CStringA;
typedef CStringT_Exported< TCHAR,
StrTraitMFC< TCHAR > > CString;
hay varias advertencias:
No debe exportar CStringT propio porque esto hará que los proyectos de ATL-only de exportar una clase especializada de CStringT .
Mediante una clase derivada exportable de CStringT minimiza tenían que funcionalidad de CStringT de re-instrumento. El código adicional se limita a reenviar constructores a la clase base de CStringT .
CString, CStringA, y CStringW deben sólo se __declspec(dllexport/dllimport) marcado cuando está compilando con DLL compartido MFC. Si vincula con una biblioteca estática de MFC, no debe marcar estas clases según lo exportado; si no, el uso interno de CString, de CStringA, y de CStringW dentro de los archivos DLL de usuario marcará CString como exportado también.