Sdílet prostřednictvím


Export tříd řetězců pomocí CStringT

V minulosti vývojáři MFC odvozeni od CString specializovat vlastní třídy řetězců. V aplikaci Microsoft Visual C++.NET (MFC 8.0) byla třída CString nahrazena třídou šablony s názvem CStringT. To poskytlo několik výhod:

  • Povolila použití třídy MFC CString v projektech ATL bez propojení ve větší statické knihovně MFC nebo knihovně DLL.

  • Pomocí nové CStringT třídy šablony můžete přizpůsobit CString chování pomocí parametrů šablony, které určují vlastnosti znaků, podobně jako šablony ve standardní knihovně C++.

  • Při exportu vlastní třídy řetězců z knihovny DLL pomocí CStringT, kompilátor také automaticky exportuje CString základní třídu. Vzhledem k tomu CString , že je sama o sobě třída šablony, může být vytvořena kompilátorem při použití, pokud kompilátor neví, že CString je importován z knihovny DLL. Pokud jste migrovali projekty z Visual C++ 6.0 do Visual C++.NET, pravděpodobně jste viděli chyby symbolů linkeru pro násobení definované CString kvůli kolizi CString importované z knihovny DLL a místně instance verze. Správný způsob, jak to udělat, je popsán níže.

Následující scénář způsobí, že linker vytvoří chyby symbolů pro násobení definovaných tříd. Předpokládejme, že exportujete odvozenou CStringtřídu (CMyString) z knihovny DLL rozšíření MFC:

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

Kód příjemce používá kombinaci a CString CMyString. Text "MyString.h" není součástí předkompilované hlavičky a některé použití CString není CMyString viditelné.

Předpokládejme, že používáte CString třídy v CMyString samostatných zdrojových souborech, Source1.cpp a Source2.cpp. V Source1.cpp použijete CMyString a #include MyString.h. V Source2.cpp použijete CString, ale ne #include MyString.h. V tomto případě si linker stěžuje na CStringT to, že se definuje násobení. Příčinou je CString import z knihovny DLL, která exportuje CMyString, a vytvoření instance místně kompilátorem prostřednictvím CStringT šablony.

Pokud chcete tento problém vyřešit, postupujte takto:

Export CStringA a CStringW (a nezbytné základní třídy) z MFC90.DLL Projekty, které zahrnují MFC, budou vždy používat knihovny MFC DLL exportované CStringA a CStringW, stejně jako v předchozích implementacích MFC.

Pak vytvořte exportovatelnou odvozenou třídu pomocí CStringT šablony, jak CStringT_Exported je uvedeno níže, například:

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

V AfxStr.h nahraďte předchozí CStringCStringA, a CStringW typedefs následujícím způsobem:

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

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

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

Existuje několik upozornění:

  • Neměli byste exportovat CStringT sami, protože to způsobí, že projekty pouze ATL exportuje specializovanou CStringT třídu.

  • Použití exportovatelné odvozené třídy z CStringT minimalizace nutnosti znovu implementovat CStringT funkce. Další kód je omezen na předávání konstruktorů do CStringT základní třídy.

  • CString, CStringAa CStringW měla by být označena __declspec(dllexport/dllimport) pouze při vytváření pomocí knihovny MFC sdílené knihovny DLL. Pokud je propojení se statickou knihovnou MFC, neměli byste tyto třídy označit jako exportované; jinak interní použití CStringknihovny DLL a CStringACStringW uvnitř uživatelských knihoven DLL se označí CString také jako exportované.

CStringT – třída

Viz také

CStringT – použití
CString – použití