Esportazione di classi String tramite CStringT

In passato, gli sviluppatori MFC hanno derivato da CString per specializzare le proprie classi di stringhe. In Microsoft Visual C++.NET (MFC 8.0), la classe CString è stata sostituita da una classe modello denominata CStringT. In questo modo sono stati offerti diversi vantaggi:

  • Ha consentito l'uso della classe MFC CString nei progetti ATL senza il collegamento nella libreria statica MFC o nella DLL più grande.

  • Con la nuova CStringT classe modello, è possibile personalizzare CString il comportamento usando parametri di modello che specificano tratti di carattere, simili ai modelli nella libreria standard C++.

  • Quando si esporta una classe stringa personalizzata da una DLL usando CStringT, il compilatore esporta automaticamente anche la CString classe di base. Poiché CString si tratta di una classe modello, può essere creata un'istanza dal compilatore quando viene usata, a meno che il compilatore non sappia che CString viene importato da una DLL. Se è stata eseguita la migrazione di progetti da Visual C++ 6.0 a Visual C++.NET, potrebbero essere stati visualizzati errori di simboli del linker per una moltiplicazione definita CString a causa del conflitto tra l'importazione CString da una DLL e la versione di cui è stata creata un'istanza locale. Il modo appropriato per eseguire questa operazione è descritto di seguito.

Lo scenario seguente causerà la generazione di errori di simboli da parte del linker per la moltiplicazione delle classi definite. Si supponga di esportare una CStringclasse derivata daCMyString una DLL di estensione MFC:

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

Il codice consumer usa una combinazione di CString e CMyString. "MyString.h" non è incluso nell'intestazione precompilata e alcuni utilizzi di CString non sono CMyString visibili.

Si supponga di usare le CString classi e CMyString in file di origine separati, Source1.cpp e Source2.cpp. In Source1.cpp usare CMyString e #include MyString.h. In Source2.cpp si usa CString, ma non si #include MyString.h. In questo caso, il linker si lamenta della CStringT moltiplicazione definita. Ciò è causato dall'importazione CString sia dalla DLL che esporta CMyStringe creata un'istanza in locale dal compilatore tramite il CStringT modello.

Per risolvere questo problema, eseguire le operazioni seguenti:

Esportare CStringA e CStringW (e le classi di base necessarie) da MFC90.DLL. I progetti che includono MFC useranno sempre la DLL MFC esportata CStringA e CStringW, come nelle implementazioni MFC precedenti.

Creare quindi una classe derivata esportabile usando il CStringT modello, come illustrato di CStringT_Exported seguito, ad esempio:

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

In AfxStr.h sostituire i typedef , CStringAe CStringW precedenti CStringcome indicato di seguito:

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

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

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

Esistono diverse avvertenze:

  • Non è consigliabile esportare CStringT se stesso perché ciò causerà l'esportazione di una classe specializzata CStringT solo di progetti ATL.

  • L'uso di una classe derivata esportabile da CStringT riduce al minimo la necessità di implementare CStringT nuovamente la funzionalità. Il codice aggiuntivo è limitato ai costruttori di inoltro alla CStringT classe base.

  • CString, CStringAe CStringW devono essere contrassegnati __declspec(dllexport/dllimport) solo quando si compila con una DLL condivisa MFC. Se si esegue il collegamento con una libreria statica MFC, non è consigliabile contrassegnare queste classi come esportate; in caso contrario, anche l'uso interno di , CStringAe CStringW all'interno delle CStringDLL utente contrassegnerà CString come esportato.

Classe CStringT

Vedi anche

Uso di CStringT
Uso di CString