_MBCS コードでの TCHAR.H データ型の使用
マニフェスト定数 _MBCS
が定義されている場合、特定の汎用テキスト ルーチンは、次のいずれかのルーチンにマップされます。
マルチバイト、文字、文字列を適切に処理する SBCS ルーチン。 この場合、文字列引数は
char*
型であることを想定しています。 たとえば、_tprintf
はprintf
にマップされ、printf
への文字列引数はchar*
型になります。 文字列型として汎用テキストのデータ型である_TCHAR
を使用する場合、_TCHAR*
はchar*
にマップされるためprintf
の仮パラメーターと実パラメーターの型は一致します。MBCS 固有ルーチン。 この場合、文字列引数は
unsigned char*
型であることを想定しています。 たとえば、_tcsrev
は、unsigned char*
型の文字列を必要とし、それを返す_mbsrev
にマップされます。 文字列型として汎用テキストのデータ型である_TCHAR
を使用する場合、_TCHAR
がchar
にマップされるため、今度は型が競合する可能性があります。
この型の競合 (および C コンパイラの警告または C++ コンパイラのエラーという結果) を回避するためには、次のような 3 つの解決方法があります。
既定の動作を使用します。 次の例のように、tchar.h はランタイム ライブラリのルーチンに対して汎用テキスト ルーチンのプロトタイプを提供します。
char * _tcsrev(char *);
既定では、
_tcsrev
のプロトタイプは Libc.lib のサンクを介して_mbsrev
にマップされます。 これにより、_mbsrev
受信パラメーターと_TCHAR*
(つまりchar *
) からunsigned char *
に送信される戻り値の型が変更されます。 この方法なら_TCHAR
を使用するときに確実に型が一致しますが、関数呼び出しのオーバーヘッドにより比較的低速になります。コードに次のプリプロセッサ ステートメントを組み込むことにより、関数のインライン展開を使用します。
#define _USE_INLINING
この方法では、tchar.h で提供されるインライン関数サンクにより、汎用テキスト ルーチンが直接、適切な MBCS ルーチンにマップされます。 どのようにマップされるかについては、例として tchar.h から抜粋した次のコードをご覧ください。
__inline char *_tcsrev(char *_s1) {return (char *)_mbsrev((unsigned char *)_s1);}
インライン展開を使用できる場合は、この方法が最適な解決法になります。確実に型が一致し、追加の時間コストが発生しないからです。
コードに次のプリプロセッサ ステートメントを組み込むことにより、直接マッピングを使用します。
#define _MB_MAP_DIRECT
この方法は、既定の動作を使用したくない場合、またはインライン展開を使用できない場合の代替手段であり、高速です。 この方法では、tchar.h から抜粋した次の例のように、汎用テキスト ルーチンがマクロによって直接、MBCS バージョンのルーチンにマップされます。
#define _tcschr _mbschr
この方法を採用する場合は、文字列の引数と文字列の戻り値に適切なデータ型を使用するように注意する必要があります。 適切に型を一致させるために型キャストを使用できます。または、汎用テキストのデータ型である
_TXCHAR
を使用できます。_TXCHAR
は SBCS コードではchar
型にマップされますが、MBCS コードではunsigned char
型にマップされます。 汎用テキストマクロの詳細については、「汎用テキストマップ」を「ランタイム ライブラリ リファレンス」で参照してください。