Tchar.h における汎用テキストのマッピング
コードを簡単に国際対応にできるように、Microsoft のランタイム ライブラリには、多くのデータ型やルーチンなどのオブジェクトに対して、Microsoft 固有の汎用テキストのマッピングが用意されています。 Tchar.h で定義されているこれらのマッピングを使用すると、#define ステートメントで定義したマニフェスト定数に応じて、1 バイト、マルチバイト、Unicode のどの文字セットにも対応できるジェネリック コードを記述できます。 汎用テキスト マッピングは Microsoft 固有の拡張機能であり、ANSI とは互換性がありません。
Tchar.h を使用することにより、同じソースから、1 バイト、マルチバイト文字セット (MBCS: Multibyte Character Set)、および Unicode の各アプリケーションをビルドできます。 Tchar.h では、プレフィックス _tcs の付いたマクロが定義されており、正しいプリプロセッサ定義に応じて str、_mbs、wcs のいずれかの関数に割り当てられます。 MBCS でビルドするには、シンボル _MBCS を定義します。 Unicode でビルドするには、シンボル _UNICODE を定義します。 1 バイト アプリケーションをビルドする場合は、どちらも定義しません (既定)。 MFC アプリケーションでは、既定で _MBCS が定義されています。
_TCHAR データ型は、Tchar.h で条件に応じて定義されます。 ビルドで _UNICODE シンボルが定義されている場合、_TCHAR は wchar_t として定義されます。それ以外の場合、1 バイトおよび MBCS のビルドでは char として定義されます。 Unicode のワイド文字データ型である wchar_t は、8 ビットの符号付き char の 16 ビット版に相当します。 国際対応のアプリケーションでは、バイトではなく _TCHAR を扱う _tcs ファミリの関数を使う必要があります。 たとえば、_tcsncpy は、n バイトではなく n 個の _TCHARs をコピーします。
1 バイト文字セット (SBCS: Single Byte Character Set) の文字列処理関数の中には、符号付きの char* パラメーターを受け取るものがあります。このため、_MBCS を定義すると、型の不一致を知らせるコンパイラの警告が生成される場合があります。 この警告を回避する方法は 3 つあります。
Tchar.h のタイプ セーフなインライン関数サンクを使用します。 これが既定の動作です。
コマンド ラインで _MB_MAP_DIRECT を定義して、Tchar.h の直接マクロを使用します。 この場合は、型を手作業で一致させる必要があります。 これは一番速い方法ですが、タイプ セーフではありません。
Tchar.h のタイプ セーフな静的リンク ライブラリ関数のサンクを使用します。 この場合は、コマンド ラインで定数 _NO_INLINING を定義します。 これは、一番時間がかかりますが、一番タイプ セーフな方法です。
汎用テキスト マッピング用のプリプロセッサ ディレクティブ
#define |
コンパイル後の状態 |
例 |
---|---|---|
_UNICODE |
Unicode (ワイド文字) |
_tcsrev は _wcsrev に割り当てられます。 |
_MBCS |
マルチバイト文字 |
_tcsrev は _mbsrev に割り当てられます。 |
なし (既定では _UNICODE も _MBCS も未定義) |
SBCS (ASCII) |
_tcsrev は strrev に割り当てられます。 |
たとえば、Tchar.h で定義されている汎用テキスト関数 _tcsrev は、プログラムで _MBCS が定義されていると _mbsrev になり、_UNICODE が定義されていると _wcsrev になります。 それ以外の場合、_tcsrev は strrev に割り当てられます。 プログラミングに便利なように他のデータ型のマッピングも Tchar.h に用意されていますが、_TCHAR が最も多く使用されます。
汎用テキストのデータ型のマップ
汎用テキスト データ型名 |
_UNICODE および _MBCS が未定義の場合 |
_MBCS が定義されている場合 |
_UNICODE が定義されている場合 |
---|---|---|---|
_TCHAR |
char |
char |
wchar_t |
_TINT |
int |
unsigned int |
wint_t |
_TSCHAR |
signed char |
signed char |
wchar_t |
_TUCHAR |
unsigned char |
unsigned char |
wchar_t |
_TXCHAR |
char |
unsigned char |
wchar_t |
_T または _TEXT |
影響なし (プリプロセッサによって削除される) |
影響なし (プリプロセッサによって削除される) |
L (後続の文字または文字列を対応する Unicode の文字または文字列に変換する) |
ルーチンや変数などのオブジェクトの汎用テキスト マッピングの一覧については、「ランタイム ライブラリ リファレンス」の「汎用テキスト マップ」を参照してください。
注意
Unicode の文字列には NULL バイトが含まれている可能性があるため、この文字列と一緒に str ファミリの関数を使用しないでください。 同様に、MBCS (または SBCS) 文字列には wcs ファミリの関数を使用しないでください。
MBCS、Unicode、および SBCS の各モデルに対応するために、_TCHAR および _tcsrev を使用するコード例を次に示します。
_TCHAR *RetVal, *szString;
RetVal = _tcsrev(szString);
_MBCS が定義されていると、プリプロセッサによって次のコードに変換されます。
char *RetVal, *szString;
RetVal = _mbsrev(szString);
_UNICODE が定義されていると、プリプロセッサによって次のコードに変換されます。
wchar_t *RetVal, *szString;
RetVal = _wcsrev(szString);
_MBCS と _UNICODE のどちらも定義されていない場合、プリプロセッサは前のコードを次のように 1 バイトの ASCII コードに割り当てます。
char *RetVal, *szString;
RetVal = strrev(szString);
このように、1 つのソース コード ファイルを記述、保守、およびコンパイルすることで、3 種類のそれぞれの文字セットに固有のルーチンを実行できます。