Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
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
CStringnei progetti ATL senza il collegamento nella libreria statica MFC o nella DLL più grande.Con la nuova
CStringTclasse modello, è possibile personalizzareCStringil 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 laCStringclasse di base. PoichéCStringsi tratta di una classe modello, può essere creata un'istanza dal compilatore quando viene usata, a meno che il compilatore non sappia cheCStringviene 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 definitaCStringa causa del conflitto tra l'importazioneCStringda 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
CStringTse stesso perché ciò causerà l'esportazione di una classe specializzataCStringTsolo di progetti ATL.L'uso di una classe derivata esportabile da
CStringTriduce al minimo la necessità di implementareCStringTnuovamente la funzionalità. Il codice aggiuntivo è limitato ai costruttori di inoltro allaCStringTclasse base.CString,CStringAeCStringWdevono 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 ,CStringAeCStringWall'interno delleCStringDLL utente contrassegneràCStringcome esportato.