使用 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
};
取用者程序代碼會使用 和CMyString
的CString
混合。 “MyString.h” 未包含在先行編譯標頭中,而且 的一些用法 CString
沒有 CMyString
可見。
假設您在 CString
個別的原始程序檔中使用 和 CMyString
類別,Source1.cpp和Source2.cpp。 在 Source1.cpp 中,您會使用 CMyString
和 #include MyString.h。 在 Source2.cpp 中,您會使用 CString
,但不會 #include MyString.h。 在此情況下,連結器會抱怨 CStringT
定義相乘。 這是因為 CString
從從導出的 DLL CMyString
匯入,並由編譯程式透過 CStringT
範本機具現化。
若要解決此問題,請執行下列動作:
從 MFC90.DLL導出 CStringA
和 CStringW
(以及必要的基類)。 包含 MFC 的專案一律會使用導出 CStringA
的 MFC DLL 和 CStringW
,如同先前的 MFC 實作一樣。
然後使用範本建立可匯出的衍生類別 CStringT
, CStringT_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
的 、 CStringA
和 CStringW
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
基類。CString
、CStringA
和CStringW
只有在您使用 MFC 共用 DLL 進行建置時,才應該標示__declspec(dllexport/dllimport)
。 如果與 MFC 靜態庫連結,則不應將這些類別標示為導出;否則,內部使用CString
、CStringA
和CStringW
的使用者 DLL 也會標示CString
為匯出。