この記事の英語版を表示するには、[英語] のチェック ボックスをオンにしてください。また、テキストにマウス ポインターを合わせると、ポップアップ ウィンドウに英語のテキストを表示することもできます。
翻訳
英語

ATL と MFC の文字列変換マクロ

 

ここで説明する文字列変換マクロは、ATL と MFC の両方に対して有効です。MFC 文字列変換の詳細については、「テクニカル ノート 59: MFC の MBCS/Unicode 変換マクロの使用」と「MFC マクロとグローバル」を参照してください。

ATL 7.0 では複数の新しい変換クラスとマクロが導入され、既存のマクロに比べて大幅に改善されています。

新しい文字列変換クラスとマクロの名前の形式は、次のとおりです。

C SourceType 2[C]DestinationType[EX]

それぞれの文字について以下に説明します。

  • SourceTypeDestinationType については次の表で説明します。

  • [C] は、変換先の型が定数である必要があることを示します。

  • [EX] は、バッファーの初期サイズをテンプレート引数として指定する必要があることを示します。

    SourceType/DestinationType

    説明

    A

    ANSI 文字列。

    W

    Unicode 文字列。

    T

    汎用文字列 (_UNICODE が定義されている場合は W、それ以外の場合は A と同等です)。

    OLE

    OLE 文字列 (W と同等)。

たとえば、Unicode 文字列から汎用文字列に変換し、変換された文字列を変更しない場合は、CW2CT を使用します。

System_CAPS_warning警告

前述したパターンの一部の順列はサポートされていません。 CA2CWCW2CA (および CA2CWEXCW2CAEX) はサポートされていません。OLE 文字列変換では、COLE2TCT2OLE (および COLE2CTCOLE2TEXCOLE2CTEXCT2COLECT2OLEEXCT2COLEEX) のみがサポートされています。詳細については、atlconv.h を参照してください。

変換された文字列が 64 文字を上回る可能性が低いと考えられる場合は、EX バージョン (CW2CTEX<64> など) を使用してスタックの領域を節約できます。

System_CAPS_noteメモ

BSTR 文字列との間での変換には、CComBSTR クラスを使用することをお勧めします。BSTR に変換するには、既存の文字列を CComBSTR のコンストラクターに渡します。BSTR から変換するには、COLE2[C]DestinationType[EX] (COLE2T など) を使用します。

バッファーを必要とする新しい変換クラス (CA2AEXCA2WEXCW2AEX、および CW2WEX) は固定サイズの静的バッファーを使用して、変換の結果を格納します。結果が大きすぎて静的バッファーに収まらない場合、クラスは malloc を使用してメモリを割り当て、オブジェクトがスコープから外れときにそのメモリを解放します。これで、以前のテキスト変換マクロとは異なり、これらのクラスを安全にループで使用でき、スタック オーバーフローは発生しなくなります。

ATL 7.0 で導入された変換マクロは、入力の NULL 文字列を認識するように最適化されています。これらのマクロは、入力パラメーターがメモリ割り当てのない NULL の場合には、NULL を返します。

既定では、ATL 変換クラスとマクロは、現在のスレッドの ANSI コード ページを変換に使用します。クラス CA2WEX または CW2AEX に基づいたマクロを使用する特定の変換について、この動作をオーバーライドする場合は、クラスのコンストラクターへの 2 つ目のパラメーターとしてコード ページを指定します。

System_CAPS_security セキュリティ メモ

文字列の長さをチェックしてから、これらのマクロに渡し、バッファー オーバーランの問題が発生しないようにします。スタック オーバーフローは、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 文字列変換マクロ

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 など) になります。 ALPSTROLELPOLESTRTLPTSTR、および WLPWSTR を表します。

マクロ名に C がある場合、このマクロは const 文字列に変換します。たとえば、W2CALPWSTRLPCSTR に変換します。

したがって、A2WLPSTRLPWSTRに、OLE2TLPOLESTRLPTSTR に、などのように変換します。

ATL 文字列変換マクロの動作は、有効なコンパイラ ディレクティブ (ある場合) によって異なります。ソースの型とターゲットの型が同じである場合、変換は実行されません。コンパイラ ディレクティブは、次のように、TOLE を変更します。

有効なコンパイラ ディレクティブ

T の変更後

OLE の変更後

なし

A

W

_UNICODE

W

W

OLE2ANSI

A

A

_UNICODE およびOLE2ANSI

W

A

変換先の文字列は、_alloca を使用して作成されます。ただし、変換先の型が BSTR である場合を除きます。 _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 で宣言)

表示: