ATL and MFC String Conversion Macros
這裡討論的字串轉換巨集對於 ATL 及 MFC 而言都有效。 如需 MFC 字串轉換的詳細資訊,請參閱 TN059:使用 MFC MBCS/Unicode 轉換巨集和 MFC 巨集和全域。
ATL 7.0 字串轉換類別和巨集
ATL 3.0 字串轉換巨集
ATL 7.0 字串轉換類別和巨集
ATL 7.0 引入了數個新轉換類別和巨集,與現有巨集相比,有了重大的改進。
新字串轉換類別和巨集的名稱採用下列格式:
CSourceType2[C]、DestinationType[EX]
其中:
SourceType 和 DestinationType 在下表中描述。
[C] 在目的型別必須是常數時存在。
[EX] 在緩衝區的初始大小必須指定為樣本引數時存在。
SourceType/DestinationType
描述
A
ANSI 字元字串。
W
Unicode 字元字串。
T
泛型字元字串 (當定義 _UNICODE 時,相當於 W,否則相當於 A)。
OLE
OLE 字元字串 (相當於 W)。
例如,若要從 Unicode 字串轉換為泛型字串而不變更已轉換的字串,請使用 CW2CT。
警告
不支援上面列出的一些部分模式排列。不支援 CA2CW 和 CW2CA (以及 CA2CWEX 和 CW2CAEX)。對於 OLE 字元字串轉換,僅支援 COLE2T 和 CT2OLE (以及 COLE2CT、COLE2TEX、COLE2CTEX、CT2COLE、CT2OLEEX 及 CT2COLEEX)。如需詳細資料,請參閱 atlconv.h。
如果已知轉換的字串不可能超過 64 個字元,則可以使用 EX 版本 (如 CW2CTEX<64>),來節省堆疊上的空間。
注意事項 |
---|
與 BSTR 字串進行來回轉換的建議方法是使用 CComBSTR 類別。若要轉換至 BSTR,請將現有字串傳遞至 CComBSTR 建構函式。若要從 BSTR 進行轉換,請使用 COLE2[C]DestinationType[EX],如 COLE2T。 |
需要緩衝區 (CA2AEX, CA2WEX、CW2AEX 及 CW2WEX) 的新轉換類別會使用固定大小的靜態緩衝區,來儲存轉換的結果。 如果結果太大,不符合靜態緩衝區,則類別會使用 malloc 來配置記憶體,當物件超出範圍時,即釋放記憶體。 與較舊的文字轉換巨集不同,這可確保在迴圈中可放心地使用這些類別,而不會產生堆疊溢位。
ATL 7.0 中引入的轉換巨集已最佳化,以了解輸入 NULL 字串。 如果輸入的參數是 NULL 而未配置任何記憶體,則這些巨集會傳回 NULL。
根據預設,ATL 轉換類別及巨集將使用目前的執行緒 ANSI 字碼頁,來進行轉換。 如果您想要基於類別 CA2WEX 或 CW2AEX,來使用巨集覆寫特定轉換的行為,請將字碼頁指定為該類別之建構函式的第二個參數。
安全性提示 |
---|
在將字串傳遞至巨集之前,請檢查字串的長度,以免發生可能的緩衝區滿溢問題。堆疊溢位是也可由 try/except 攔截的例外狀況。 |
較舊字串轉換巨集與新字串轉換類別之間,存在數個重要的區別:
舊 ATL 3.0 轉換巨集 |
新 ATL 7.0 轉換類別 |
---|---|
在堆疊上配置記憶體。 |
對小型字串使用堆疊記憶體。 如果堆疊不是足夠大,則使用堆積。 |
當函式結束時,會釋放字串。 |
當變數超出範圍時,會釋放字串。 |
無法在例外狀況處理常式中使用。 |
可以在例外狀況處理常式中使用。 |
不適用於在迴圈中使用。 在函式結束之前,記憶體用量會一直增長。 |
支援在迴圈中使用。 迴圈範圍可確保在每一次反覆時釋放記憶體。 |
不適用於大型字串。 堆疊空間有限。 |
可以處理大型字串。 字串將在堆積上配置。 |
通常需要定義 USES_CONVERSION。 |
永不需要定義 USES_CONVERSION。 |
OLE 的意義取決於 OLE2ANSI 的定義。 |
OLE 一律相當於 W。 |
範例
程式碼
//Example 1
// Convert LPCWSTR to LPCSTR.
void ExampleFunction1(LPCWSTR pszW)
{
// Create an instance of CW2A, called pszA,
// and initialize it with pszW.
CW2A pszA(pszW);
// pszA works like an LPCSTR, and can be used thus:
ExampleFunctionA(pszA);
// Note: pszA will become invalid when it goes out of scope.
}
// Example 2
// Use a temporary instance of CW2A.
void ExampleFunction2(LPCWSTR pszW)
{
// Create a temporary instance of CW2A,
// and initialize it with pszW.
ExampleFunctionA(CW2A(pszW));
// Note: the temporary instance becomes invalid
// after the execution of the statement above.
}
// Example 3
// Incorrect use of conversion macros.
void ExampleFunction3(LPCWSTR pszW)
{
// Create a temporary instance of CW2A,
// save a pointer to it and then delete
// the temportary instance.
LPCSTR pszA = CW2A(pszW);
// The pszA in the following line is an invalid pointer,
// as the instance of CW2A has gone out of scope.
ExampleFunctionA(pszA);
}
有關暫時類別執行個體的警告
應該重點強調下列程式碼並非優良的程式碼:
LPCTSTR szr = CA2T(szReplaceFile);
使用 ATL 3.0 巨集,可接受使用:
LPCTSTR szr = A2T(szReplaceFile);
因為在目前函式結束之前,不會釋放由轉換函式配置的記憶體。 相同的程式碼無法配合新類別使用。
此程式碼:
LPCTSTR szr = CA2T(szReplaceFile);
相當於這個:
LPCTSTR szr;
{
CA2T temp(szReplaceFile);
szr = temp.operator LPTSTR();
}
因為由暫存物件配置並從轉型運算子傳回的記憶體會在暫存物件終結時終結,所以在 szr 中使用該值會產生不適當的結果。
請改用此程式碼:
CA2T szr(szReplaceFile);
轉型運算子讓 CA2T 物件看起來像 LPCTSTR。
進階使用方式
預設靜態緩衝區大小為 128 個字元。 如果為了特定轉換必須變更緩衝區大小,請使用巨集的 EX 版本,並將緩衝區大小指定為樣板引數。
// Example 4
// Changing the size of the buffer.
void ExampleFunction4(LPCWSTR pszW)
{
// Use a 16-character buffer.
ExampleFunctionA(CW2AEX<16>(pszW));
}
以下範例會將字碼頁指定為類別之建構函式的第二個參數。
// Example 5
// Specifying the code page.
void ExampleFunction5(LPCWSTR pszW)
{
// Convert to the Macintosh code page
ExampleFunctionA(CW2A(pszW, CP_MACCP));
}
ATL 3.0 字串轉換巨集
原始文字轉換巨集仍然可用,並在下表中列出:
ATL 3.0 字串轉換巨集
A2BSTR |
OLE2A |
T2A |
W2A |
A2COLE |
OLE2BSTR |
T2BSTR |
W2BSTR |
A2CT |
OLE2CA |
T2CA (已取代。 請改用 T2CA_EX 或 CT2CA)。 |
W2CA |
A2CW |
OLE2CT |
T2COLE |
W2COLE |
A2OLE |
OLE2CW |
T2CW |
W2CT |
A2T |
OLE2T |
T2OLE |
W2OLE |
A2W |
OLE2W |
T2W |
W2T |
使用這些巨集的語法如下所示:
MACRONAME( string_address )
例如:
A2W(lpa);
在巨集名稱中,來源字串類型在左側 (例如,A) 而目的字串類型在右側 (例如,W)。 A 代表 LPSTR,OLE 代表 LPOLESTR,T 代表 LPTSTR 而 W 代表 LPWSTR。
如果巨集名稱中有 C,則該巨集會轉換為 const 字串。 例如,W2CA 會將 LPWSTR 轉換為 LPCSTR。
如此,A2W 會將 LPSTR 轉換為 LPWSTR,OLE2T 會將 LPOLESTR 轉換為 LPTSTR,以此類推。
ATL 字串轉換巨集的行為取決於作用中的編譯器指示詞 (如果有的話)。 如果來源與目的類型相同,則不會發生轉換。 編譯器指示詞會如下變更 T 和 OLE:
作用中的編譯器指示詞 |
T 變為 |
OLE 變為 |
---|---|---|
無 |
A |
W |
_UNICODE |
W |
W |
OLE2ANSI |
A |
A |
_UNICODE 和OLE2ANSI |
W |
A |
除了目的類型為 BSTR 之外,會使用 _alloca 建立目的字串。 使用 _alloca 在堆疊外配置記憶體,以便您的函式傳回值時自動進行清除。 根據預設,此巨集一次最多僅會轉換 500KB。
當使用 ATL 字串轉換巨集時,請在函式的開頭指定 USES_CONVERSION 巨集,以避免編譯器錯誤。 例如:
void StringFunc(LPSTR lpsz)
{
USES_CONVERSION;
LPWSTR x = A2W(lpsz);
// Do something with x
wprintf_s(L"x is %s", x);
}
需求
標頭檔:AtlBase.h、AtlConv.h (在 AtlConv.h 中宣告)
請參閱
參考
DEVMODE and TEXTMETRIC String Conversion Macros