次の方法で共有


_MBCS コードでの TCHAR.H データ型の使用

マニフェスト定数 _MBCS が定義されている場合、特定の汎用テキスト ルーチンは、次のいずれかのルーチンにマップされます。

  • マルチバイト、文字、文字列を適切に処理する SBCS ルーチン。 この場合、文字列引数は char* 型であることを想定しています。 たとえば、_tprintfprintf にマップされ、printf への文字列引数は char* 型になります。 文字列型として汎用テキストのデータ型である _TCHAR を使用する場合、_TCHAR*char* にマップされるため printf の仮パラメーターと実パラメーターの型は一致します。

  • MBCS 固有ルーチン。 この場合、文字列引数は unsigned char* 型であることを想定しています。 たとえば、_tcsrev は、unsigned char* 型の文字列を必要とし、それを返す _mbsrev にマップされます。 文字列型として汎用テキストのデータ型である _TCHAR を使用する場合、_TCHARchar にマップされるため、今度は型が競合する可能性があります。

この型の競合 (および 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 型にマップされます。 汎用テキストマクロの詳細については、「汎用テキストマップ」を「ランタイム ライブラリ リファレンス」で参照してください。

関連項目

tchar.h における汎用テキストのマッピング