Exportieren von Zeichenfolgenklassen mit CStringT

In der Vergangenheit haben MFC-Entwickler von CString der Spezialisierung ihrer eigenen Zeichenfolgenklassen abgeleitet. In Microsoft Visual C++.NET (MFC 8.0) wurde die CString-Klasse durch eine Vorlagenklasse namens CStringT ersetzt. Dies hat mehrere Vorteile zur Verfügung gestellt:

  • Die MFC-Klasse CString konnte in ATL-Projekten ohne Verknüpfung in der größeren statischen MFC-Bibliothek oder DLL verwendet werden.

  • Mit der neuen CStringT Vorlagenklasse können Sie das Verhalten mithilfe von Vorlagenparametern anpassen CString , die Zeicheneigenschaften angeben, ähnlich wie die Vorlagen in der C++-Standardbibliothek.

  • Wenn Sie Ihre eigene Zeichenfolgenklasse aus einer DLL exportieren, CStringTexportiert der Compiler auch automatisch die CString Basisklasse. Da CString es sich selbst um eine Vorlagenklasse handelt, kann sie beim Verwenden vom Compiler instanziiert werden, es sei denn, der Compiler ist sich bewusst, dass CString aus einer DLL importiert wird. Wenn Sie Projekte von Visual C++ 6.0 zu Visual C++.NET migriert haben, wurden möglicherweise Linkersymbolfehler für eine multiplizierte CString Definition aufgrund der Kollision der CString importierten DLL und der lokal instanziierten Version angezeigt. Die richtige Vorgehensweise hierzu wird unten beschrieben.

Das folgende Szenario führt dazu, dass der Linker Symbolfehler für multiplizierte definierte Klassen erzeugt. Gehen Sie davon aus, dass Sie eine CStringabgeleitete Klasse (CMyString) aus einer MFC-Erweiterungs-DLL exportieren:

// MyString.h
class AFX_EXT_CLASS CMyString : public CString
{
   // Your implementation code
};

Der Verbrauchercode verwendet eine Mischung aus CString und CMyString. "MyString.h" ist nicht im vorkompilierten Header enthalten, und einige Verwendungen von CString "MyString.h" sind CMyString nicht sichtbar.

Gehen Sie davon aus, dass Sie die CString Und-Klassen CMyString in separaten Quelldateien, Source1.cpp und Source2.cpp verwenden. In Source1.cpp verwenden CMyString und #include MyString.h. In Source2.cpp verwenden CStringSie , aber nicht #include MyString.h. In diesem Fall beschwert sich der Linker darüber CStringT , dass er multipliziert wird. Dies wird dadurch verursacht, dass CString beide aus der DLL importiert werden, die CMyStringvom Compiler über die CStringT Vorlage lokal exportiert und instanziiert wird.

Gehen Sie wie folgt vor, um dieses Problem zu beheben:

Exportieren CStringA und CStringW (und die erforderlichen Basisklassen) aus MFC90.DLL. Projekte, die MFC enthalten, verwenden immer die exportierte CStringA MFC-DLL und CStringW, wie in früheren MFC-Implementierungen.

Erstellen Sie dann eine exportierbare abgeleitete Klasse mithilfe der CStringT Vorlage, wie CStringT_Exported unten dargestellt, z. B.:

#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
};

Ersetzen Sie in AfxStr.h die vorherigen CStringCStringA, und CStringW typedefs wie folgt:

typedef CStringT_Exported< wchar_t, 
      StrTraitMFC< wchar_t > > CStringW;

typedef CStringT_Exported< char,
      StrTraitMFC< char > > CStringA;

typedef CStringT_Exported< TCHAR,
      StrTraitMFC< TCHAR > > CString;

Es gibt mehrere Vorbehalte:

  • Sie sollten sich nicht selbst exportieren CStringT , da dies dazu führt, dass NUR ATL-Projekte eine spezialisierte CStringT Klasse exportieren.

  • Die Verwendung einer exportierbaren abgeleiteten Klasse verhindert CStringT , dass die Funktionalität erneut implementiert CStringT werden muss. Zusätzlicher Code ist auf das Weiterleiten von Konstruktoren an die CStringT Basisklasse beschränkt.

  • CString, CStringAund CStringW sollte nur markiert __declspec(dllexport/dllimport) werden, wenn Sie mit einer gemeinsam genutzten MFC-DLL erstellen. Wenn Sie eine Verknüpfung mit einer statischen MFC-Bibliothek herstellen, sollten Sie diese Klassen nicht als exportiert markieren. andernfalls werden interne Verwendungen von , CStringAund CStringW innerhalb von CStringBenutzer-DLLs ebenfalls als exportiert markiertCString.

CStringT-Klasse

Siehe auch

Verwenden von CStringT
Verwenden von CString