ABも様々な文字型が氾濫するようになりました。とりあえず主要なものをここにまとめておきます。
今日は大雑把ですが、細かい話です。具体的な使用例などの話は翌日付以降になります。
注意:今日の話は、全て文字型そのものや文字型へのポインタ、文字型の配列を扱うときの話です。ここで紹介する文字列は全てStringに変換できるので、基本的に文字列はみなString型の変数へ代入しましょう。
まずは並べてみます。
- Byte
- SByteへ移行。
- SByte
- 常にマルチバイト文字。Windows APIに合わせてTypeDef CHAR = SByteとしたいが、コンパイラ組み込みのCharがあるので遠慮している。
- Char, TCHAR
- Windows API用。UNICODEの定義に合わせてマルチバイト文字とワイド文字とに切り替わる。TCHARはCharのTypeDef。
- StrChar
- String用。基本的に__STRING_IS_NOT_ALWAYS_UNICODEが定義されているとマルチバイトになる。ただしUNICODEが定義されているとそれは無視され必ずワイド文字になる。
- WCHAR
- 常にワイド文字。
常にマルチバイト/ワイド文字にしたい場合はSByte/WCHARを使うことになります。基本的にはChar/TCHARとStrCharが頻繁に使われることになると思います。
なお、StrCharを除いてWindows APIのTypeDefが存在します。*SByteより意味が明確になると言うことでPSTR/PCSTR系だけは使っておくのが個人的なお勧めです。
*SByte | *TCHAR | *WCHAR |
---|---|---|
PSTR, LPSTR | PTSTR, LPTSTR | PWSTR, LPWSTR |
PCSTR, LPCSTR | PCTSTR, LPCTSTR | PCWSTR, LPCWSTR |
今のところABにConstな型と言う概念はないのでC付きの型はそうでない型と違いはありません。気になる人(自分含む)は概念的に使い分けておくと、もしも将来Constな型が存在するようになったときに幸せになれるかもしれません。
次は状況別にどうなるか記します。
- UNICODEが定義されている
- SByte: マルチバイト文字、Char, StrChar, WCHAR: ワイド文字
- 上と下のどちらも定義されていない
- SByte, Char; マルチバイト文字、StrChar, WCHAR: ワイド文字(このとき__STRING_UNICODE_WINDOWS_ANSIが定義される)
- __STRING_IS_NOT_ALWAYS_UNICODEが定義されている
- SByte, Char, StrChar: マルチバイト文字、WCHAR: ワイド文字(このとき__STRING_IS_NOT_UNICODEが定義される)
つまり状態に応じて常にUNICODE, __STRING_UNICODE_WINDOWS_ANSI, __STRING_IS_NOT_UNICODEのどれか1つが必ず定義されます。
- UNICODE状態ではW版のAPIが使われるため、出来上がった実行ファイルをWindows 9xで動かせなくなる。しかし文字の取り扱いはワイド文字1つに絞られるので単純。
- __STRING_UNICODE_WINDOWS_ANSI状態ではA版のAPIが使われるため、出来上がった実行ファイルをWindows 9xで動かせる。しかし、APIを頻繁に呼び出す場合文字の取り扱いが若干面倒。
- __STRING_IS_NOT_UNICODE状態は完全にAB4までと同じ状態。文字の取り扱いもマルチバイト1つに絞られるので単純。
ちなみにVisual Basicは__STRING_UNICODE_WINDOWS_ANSI状態に近いです。Declareで外部の関数を呼び出すときには自動的に文字コードの変換が行われるので、基本的には意識しなくてすむようになっているのです。
次は文字列の変換についてです。
Stringへの変換は、コンストラクタ、代入演算子、Assignメソッドで行え、連結演算子 (+, &)でも自動的に変換されるので、冒頭に書いたとおり、基本的にはどんな文字列もとりあえずStringへ放り込むのが楽です。
お互いに変換する関数としてGetStrが存在します。いくつも多重定義されていますが、全てGetStr(入力, 出力)という形式です。入力は次のいずれかです。
- 任意の文字列へのポインタ(ヌル文字終端) – lstrlenA/Wで文字列の長さが計られます。
- 上に加え、文字列の長さを表す引数 As SIZE_Tの2つの引数 – 文字列の長さがわかっている場合には、上記より効率的です。
- String文字列
出力はPCSTRとPCWSTRの2種類が多重定義されています。そのためChar/TCHAR文字列やStrChar文字列も対応できます。戻り値は出力先の文字列の長さです。
出力先を明確にした関数としてGetMBStr (*Byte), GetTCStr (*TCHAR), GetSCStr (*StrChar), GetWCStr (*WCHAR)があります。括弧内が出力先の型となります。全てそのままGetStrへ呼び出すだけの関数として定義されています。
また、文字列を戻り値として得られる関数としてToMBStr, ToTCStr, ToSCStr, ToWCStrがあります。出力先が最後の引数から戻り値へ移動しています。その代わり出力文字列の長さは捨てられます。
これら変換関数はメモリ確保にGC_malloc_atomicを使います。メモリの解放を考える必要はありません。また、変換する必要が無い組み合わせでは単純にポインタ値の代入で済ませます。
スポンサード リンク |