ATL と MFC の文字列変換マクロ
更新 : 2007 年 11 月
ここで説明する文字列変換マクロは ATL と MFC の両方に有効です。MFC の文字列変換の詳細については、「テクニカル ノート 59: MFC の MBCS/Unicode 変換マクロの使用」および「MFC マクロとグローバル」を参照してください。
ATL 7.0 文字列変換のクラスおよびマクロ
ATL 3.0 文字列変換マクロ
ATL 7.0 文字列変換のクラスおよびマクロ
ATL 7.0 には、いくつかの新しい変換クラスと変換マクロが用意されており、既存のマクロよりも機能が大幅に向上しています。
新しい文字列変換のクラスとマクロの名前の形式は次のとおりです。
CSourceType2[C]DestinationType[EX]
指定項目 :
SourceType と DestinationType については、以下の表で説明しています。
[C] は、変換先の型を定数にする必要があるときに設定されます。
[EX] は、バッファの初期サイズをテンプレート引数として指定する必要があるときに設定されます。
変換元の型/変換先の型
説明
A
ANSI 文字列です。
W
Unicode 文字列です。
T
汎用文字列です。_UNICODE が定義されている場合は W と等価です。それ以外の場合は A と等価です。
OLE
OLE 文字列です。W と等価です。
たとえば、変換される文字列を変更せずに Unicode 文字列を汎用文字列に変換するには、CW2CT を使用します。
変換される文字列が 64 文字を超えないことが明らかな場合は、CW2CTEX<64> などの EX バージョンを使用してスタックの領域を節約できます。
メモ : |
---|
BSTR 文字列との変換には、CComBSTR クラスを使用することをお勧めします。BSTR に変換するには、既存の文字列を CComBSTR のコンストラクタに渡します。BSTR から変換するには、COLE2T などの COLE2[C]DestinationType[EX] を使用します。 |
バッファ (CA2AEX、CA2WEX、CW2AEX、および CW2WEX) を必要とする新しい変換クラスでは、固定サイズの静的バッファを使用して変換結果を格納します。結果のサイズが大きすぎて静的バッファに格納できない場合、クラスは malloc を使用してメモリを割り当て、オブジェクトがスコープ外に出たときにメモリを解放します。このため、以前の形式のテキスト変換マクロとは異なり、これらのクラスはループ内で安全に使用でき、スタック オーバーフローが発生しません。
ATL 7.0 で導入された変換マクロは、入力の NULL 文字列を認識するように最適化されています。これらのマクロは、入力パラメータが NULL である場合、メモリを割り当てることなく NULL を返します。
既定では、ATL 変換クラスおよび変換マクロは現在のスレッドの ANSI コード ページを変換に使用します。CA2WEX クラスと CW2AEX クラスに基づくマクロを使用する特定の変換のためにこの動作をオーバーライドする場合は、クラスのコンストラクタの 2 番目のパラメータとしてコード ページを指定します。
セキュリティに関するメモ : |
---|
マクロに文字列を渡す前に、文字列の長さをチェックして、発生する可能性のあるバッファ オーバーランを回避します。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));
}
コード ページをクラスのコンストラクタに対して 2 番目のパラメータとして指定する例を次に示します。
// 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 は LPTSTR、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 を使用するとスタックからメモリを割り当てるため、関数が制御を返すとき、自動的にメモリが解放されます。既定では、このマクロは一度に最大 500 KB しか変換できません。
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 および TEXTMETRIC の各文字列変換マクロ