ATL 和 MFC 字串轉換巨集
討論字串轉換巨集此處為 ATL 和 MFC 是有效的。 如需 MFC 字串轉換的詳細資訊,請參閱 TN059:使用 MFC MBCS/Unicode 轉換巨集 和 MFC 巨集和 Globals。
ATL 7.0 字串轉換類別和巨集
ATL 3.0 字串轉換巨集
ATL 7.0 字串轉換類別和巨集
ATL 7.0 引入許多新的轉換類別和巨集,其可提供現有的巨集的改進。
新的字串轉換類別和巨集名稱的形式為:
CSourceType2C 的 EXDestinationType
其中:
SourceType 和 DestinationType 在下表中說明。
是C存在,但是當目的型別必須為常數時。
是EX存在時,則必須指定緩衝區的初始大小做為樣板引數時。
SourceType/DestinationType
描述
A
ANSI 字元字串。
W
Unicode 字元字串。
T
泛型字串 (相當於 W,當 _UNICODE 定義,等於則為 A)。
OLE
OLE 字串 (相當於 W)。
例如,將 Unicode 字串轉換成泛型字串,且不會變更轉換後的字串,請使用 CW2CT。
如果知道轉換的字串不可超過 64 個字元, EX 版本,例如,在 **CW2CTEX<64>**堆疊來節省空間。
注意事項 |
---|
建議的方式來回轉換成的 BSTR 字串會使用 CComBSTR 類別。要轉換為 BSTR,請將現有字串 CComBSTR.建構函式若要從 BSTR 轉換,請使用 COLE2CDestinationTypeEX,例如 COLE2T。 |
需要緩衝區的新轉換類別 (CA2AEX、 CA2WEX、 CW2AEX和 CW2WEX) 使用具有固定大小的靜態緩衝區存放已轉換的結果。 如果結果太大而無法符合這個靜態緩衝區,使用 malloc,類別配置記憶體,釋放記憶體,當物件超出範圍時。 這可確保,跟舊版的文字轉換巨集,這些類別是安全使用迴圈,並不會讓堆疊溢位。
在 ATL 引入的轉換巨集 7.0 最佳化已知輸入 NULL 字串。 這些巨集就會傳回 NULL ,如果輸入參數是 NULL 未配置任何記憶體。
根據預設, ATL 轉換類別和巨集來轉換會使用目前執行緒的 ANSI 字碼頁。 如果您要覆寫特定轉換的行為使用以類別為基礎的巨集 CA2WEX 或 CW2AEX,指定字碼頁做為第二個參數傳遞給建構函式的類別。
安全性提示 |
---|
在傳遞之前檢查字串長度為這些巨集避免可能的緩衝區滿溢問題。堆疊溢位是也可以攔截與嘗試/以外的例外狀況。 |
在舊版的字串轉換巨集和新的字串轉換類別之間的幾個重要的差異:
舊的 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);
轉型運算子來完成 CA2 T 物件看起來 LPCTSTR。
進階使用方式
預設的靜態緩衝區大小為 128 個字元。 如果需要特定轉換變更緩衝區大小,請使用巨集的目前版本,並指定緩衝區大小當做樣板引數使用。
// 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 變成 |
---|---|---|
None |
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);
}
需求
Header file: AtlBase.h, AtlConv.h (宣告在 AtlConv.h)