共用方式為


使用 CStringT 匯出字串類別

過去,MFC 開發人員衍生自 CString 來專門自己的字串類別。 在 Microsoft Visual C++.NET (MFC 8.0)中, CString 類別已由稱為 CStringT 的範本類別取代。 這提供了數個優點:

  • 它允許在 ATL 專案中使用 MFC 類別,而不需在較大的 MFC CString 靜態程式庫或 DLL 中連結。

  • 使用新的 CStringT 範本類別,您可以使用指定字元特性的範本參數來自訂 CString 行為,類似于 C++ 標準程式庫中的範本。

  • 當您使用 CStringT 從 DLL 匯出自己的字串類別時,編譯器也會自動匯出 CString 基類。 因為 CString 本身是範本類別,所以除非編譯器知道 CString 從 DLL 匯入,否則它可能會由編譯器具現化。 如果您已將專案從 Visual C++ 6.0 移轉至 Visual C++.NET,您可能會因為從 DLL 和本機具現化版本匯入的衝突 CString 而看到乘法 CString 定義的連結器符號錯誤。 執行此動作的適當方式如下所述。

下列案例會導致連結器產生相乘定義類別的符號錯誤。 假設您要從 MFC 擴充 DLL 匯出 CString 衍生類別 ( CMyString ) :

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

取用者程式碼會使用 和 CMyStringCString 混合。 「MyString.h」 未包含在先行編譯標頭中,而且 的一些用法 CString 沒有 CMyString 可見。

假設您在不同的原始程式檔 Source1.cpp 和 Source2.cpp 中使用 CStringCMyString 類別。 在 Source1.cpp 中,您會使用 CMyString 和 #include MyString.h。 在 Source2.cpp 中,您會使用 CString ,但不會 #include MyString.h。 在此情況下,連結器會抱怨 CStringT 定義相乘。 這是因為 CString 從從匯出 的 DLL CMyString 匯入,並由編譯器透過 CStringT 範本在本機具現化。

若要解決此問題,請執行下列動作:

從 MFC90.DLL 匯出 CStringACStringW (以及必要的基類)。 包含 MFC 的專案一律會使用匯出 CStringA 的 MFC DLL 和 CStringW ,如同先前的 MFC 實作一樣。

然後使用範本建立可匯出的衍生類別 CStringTCStringT_Exported 例如:

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

在 AfxStr.h 中,取代先前 CString 的 、 CStringACStringW typedefs,如下所示:

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

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

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

有數個注意事項:

  • 您不應該匯出 CStringT 本身,因為這會導致僅限 ATL 的專案匯出特製化 CStringT 類別。

  • 使用可匯出的衍生類別 CStringT ,將必須重新實 CStringT 作功能降到最低。 其他程式碼僅限於將建構函式轉送至 CStringT 基類。

  • CStringCStringACStringW 只有在您使用 MFC 共用 DLL 進行建置時,才應該標示 __declspec(dllexport/dllimport) 。 如果與 MFC 靜態程式庫連結,則不應將這些類別標示為匯出;否則,內部使用 CStringCStringACStringW 的使用者 DLL 也會標示 CString 為匯出。

CStringT 類別

另請參閱

使用 CStringT
使用 CString