これまでの授業にてUNIX上のプログラミング環境で用いてきた、ANSI(The American National Standard Institute)規格のC言語では、文字型といえばASCIIコードのchar型、つまり8ビット=1バイトで境界整列されるものだけを意味していた。 そこでは日本語の扱いについて面倒な説明を一切省いてきた。 正確に言えば日本語はコメントのみに限定して許可してきた。
しかしながら近年では国際化規約にあわせてUnicode標準と呼ばれる文字コード体系が考案され(1993年)、世界の主要言語における全ての文字を16ビット(2バイト)で統一的に表すことが可能となっている。 その一方で、これまでのchar型との互換性が問題となってきている。
そこでWindowsではいち早く、Unicode型の環境でも非Unicode型の環境でも同一のソースコードで互換性を保てるように、APIの言語仕様を定めている。 見慣れないデータ型、LPCStr、TCHAR等はその一例である。 以下、少し詳しく説明していこう。
これまで(非Unicodeの環境で)日本語を扱う場合には,、1バイト文字と2バイト文字が混在する方式を採用してきた。 これをマルチバイト文字セットと呼ぶ。 マルチバイト文字セットの問題は、第1に日本語の文字セットと中国語の文字セットが異なるというように、国際化の点で統一化しにくいということにある。 そして第2に、1バイト文字と2バイト文字が混在すると、文字列の中の各文字を1バイト文字か2バイト文字か毎回調べる必要があるため、プログラム自体が複雑な構造になり、処理の手間もかかる。
そこでANSI Cでは、全ての文字を2バイトで表すワイド文字、wchar_t型を新たに定めた。 これにより,バイト数の異なる文字が混在することが無くなり、事実上Unicode(世界中の主要な言語における全ての文字を統一的に表す文字コード)を実現している。 こうして、アルファベット以外の特殊文字を統一的に扱うことができるようになった。
次の問題は、世界中にある全てのコンピュータがこのUnicodeに対応しているかということである。 残念ながらWindows95や98の時代にはUnicodeの必要性が少なかったため対応しておらず、事実上WindowsME、WindowsNT以降のWindows(2000,XP,VISTA)でのみ対応している。 従って比較的古いシステムでUnicode用のプログラムを動かすには、移植(プログラムの書き直し)作業が必要になってしまう。
Win32APIでは、マルチバイト文字とUnicodeの混乱を解決する方法として、独自のデータ型の仕様を用いている。 この方法では、ASCIIとしてコンパイルする場合は1バイトの変数、Unicodeとしてコンパイルする場合は2バイトの変数として処理するように、プリプロセスする方法を用いている。
文字列型 | 解釈 |
---|---|
WCHAR | wchar_t(2バイト文字コード)と同義 |
TCHAR | Unicodeが定義されている場合WCHAR,それ以外はCHAR(charと同義) |
TBYTE | Unicodeが定義されている場合WCHAR,それ以外はCHAR(charと同義) |
PStr ,LPStr | NULLで終わる8ビット文字列へのポインタ |
PCStr ,LPCStr | NULLで終わる固定的8ビット文字列へのポインタ |
PWStr ,LPWStr | NULLで終わる16ビット文字列へのポインタ |
PCWStr ,LPCWStr | NULLで終わる固定的16ビット文字列へのポインタ |
PTStr | Unicodeが定義されている場合PWStr,それ以外はPStr |
PCTStr | Unicodeが定義されている場合PCWStr,それ以外はPCStr |
LPTStr | Unicodeが定義されている場合LPWStr,それ以外はLPStr |
LPCTStr | Unicodeが定義されている場合LPCWStr,それ以外はLPCStr |
上の表より、Win32APIが、8ビットか16ビット、固定文字列か非固定文字列かという分類で都合4種類の文字列を、Unicode環境の有無に応じて使い分けられることが分かる。
次に、文字列リテラルについての注意事項を述べる。 文字列リテラルとは、固定された文字列で例えば"Hello! World"などのことである。 この例の場合は言うまでもなく8ビットの文字列リテラルである。 ワイド文字リテラルに対してはL接頭辞を文字列の頭に付し、L"Hello! World"とすれば良い。 ただしこれをUnicodeの有無でいちいち切り替えるのは面倒である。 そのため、Win32APIではTEXTというマクロが用意されている。 これをプリプロセッサに通すこと、すなわち
をプリプロセスすることで、Unicodeが定義されていればワイド文字リテラルのL"Hello! World"として、そうでなければ8ビット文字リテラルの"Hello! World"としてコンパイルしてくれる。 従って、国際化されたソースコードでは、文字リテラル "何か文章" を常に、TEXT("何か文章") としておくことが肝要である。
最後に重要なことを1つ。 Visual Studioにおける、Unicode環境とマルチバイト環境の切り替え方について説明する。 メニューバーの[プロジェクト]から [○プロジェクト名○のプロパティ]を開き、[構成プロパティ]→[詳細]を開き、[文字セット]を[Unicode文字セットを使用する]から[マルチバイト文字セットを使用する]に変更する。
これはVisual Studio 2022での設定であるが、他のバージョンでもほぼ同じような方法で設定できる。 Visual Studio 2022での 詳しい設定方法はこちらの「開発環境の準備手順」に書いてある。