Udostępnij za pośrednictwem


Eksportowanie klas ciągów przy użyciu CStringT

W przeszłości deweloperzy MFC pochodzili z CString , aby specjalizować własne klasy ciągów. W programie Microsoft Visual C++.NET (MFC 8.0) klasa CString została zastąpiona przez klasę szablonu o nazwie CStringT. Zapewniało to kilka korzyści:

  • Klasa MFC mogła być używana w projektach ATL bez łączenia w większej bibliotece statycznej MFC CString lub bibliotece DLL.

  • Dzięki nowej CStringT klasie szablonu można dostosować CString zachowanie przy użyciu parametrów szablonu, które określają cechy znaków, podobnie jak szablony w standardowej bibliotece języka C++.

  • Podczas eksportowania własnej klasy ciągów z biblioteki DLL przy użyciu CStringTprogramu kompilator automatycznie eksportuje klasę bazową CString . Ponieważ CString sam jest klasą szablonu, może zostać utworzone przez kompilator, jeśli jest używany, chyba że kompilator jest świadomy, że CString jest importowany z biblioteki DLL. W przypadku migrowania projektów z programu Visual C++ 6.0 do programu Visual C++.NET mogą wystąpić błędy symboli konsolidatora zdefiniowane przez mnożenie CString ze względu na kolizję CString zaimportowanego z biblioteki DLL i lokalnie utworzonej wersji. Odpowiedni sposób, aby to zrobić, jest opisany poniżej.

Poniższy scenariusz spowoduje, że konsolidator generuje błędy symboli dla mnożenia zdefiniowanych klas. Załóżmy, że eksportujesz klasę pochodną CString(CMyString) z biblioteki DLL rozszerzenia MFC:

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

Kod odbiorcy używa kombinacji elementów CString i CMyString. Element "MyString.h" nie jest uwzględniony w prekompilowanej nagłówku, a niektóre użycie elementu nie ma CMyString widocznegoCString.

Załóżmy, że klasy i CMyString są używane CString w osobnych plikach źródłowych, Source1.cpp i Source2.cpp. W Source1.cpp używasz CMyString i #include MyString.h. W Source2.cpp użyj polecenia CString, ale nie #include MyString.h. W takim przypadku konsolidator będzie narzekać na CStringT zdefiniowanie mnożenia. Jest to spowodowane CString tym, że zarówno importowane z biblioteki DLL, która eksportuje CMyStringelement , jak i tworzone lokalnie przez kompilator za pośrednictwem szablonu CStringT .

Aby rozwiązać ten problem, wykonaj następujące czynności:

Eksportuj CStringA i CStringW (oraz niezbędne klasy bazowe) z MFC90.DLL. Projekty zawierające MFC zawsze będą używać wyeksportowanych CStringA bibliotek DLL MFC i CStringW, jak w poprzednich implementacjach MFC.

Następnie utwórz klasę pochodną z możliwością eksportowania przy użyciu szablonu CStringT , jak CStringT_Exported pokazano poniżej, na przykład:

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

W pliku AfxStr.h zastąp poprzednie CStringdefinicje typów , CStringAi CStringW w następujący sposób:

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

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

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

Istnieje kilka zastrzeżeń:

  • Nie należy eksportować CStringT samego siebie, ponieważ spowoduje to eksportowanie wyspecjalizowanych CStringT klas tylko do projektów ATL.

  • Korzystanie z klasy pochodnej z możliwością eksportowania zminimalizuje CStringT konieczność ponownego zaimplementowania CStringT funkcji. Dodatkowy kod jest ograniczony do przekazywania konstruktorów do klasy bazowej CStringT .

  • CString, CStringAi CStringW powinny być oznaczone __declspec(dllexport/dllimport) tylko podczas kompilowania z udostępnioną biblioteką DLL MFC. W przypadku łączenia z biblioteką statyczną MFC nie należy oznaczać tych klas jako eksportowanych; w przeciwnym razie wewnętrzne użycie CStringbibliotek DLL , CStringAi CStringW wewnątrz użytkownika będzie oznaczać CString , jak również eksportowane.

CStringT, klasa

Zobacz też

Użycie CStringT
Użycie CString