(2018.9) 新規作成.
wxWidgets 3.0 になって, 文字列が Unicode ベースになった。しかしながら、ビルドオプションを考慮しなければならず、微妙に面倒になっている.
wxString
クラスwxWidgets 3.0 の文字列は, Unicode "Code Point" (32bit) 単位ではない。"Code Unit" 単位で扱われる。
Unicode は "文字" が Code Point と一致していない。1文字が複数の Code Point になりうるし、逆もありうる.
https://www.unicode.org/reports/tr17/
最近では Unicode 異体字シーケンス (Ideographic Variation Sequence; IVS) が導入され、漢字も1 code point とは限らない。親字の後に Variation Selector (VS; 字形選択子) を続けて、字形を選択する. この符号列を Ideographic Variation Sequence という。
wxWidgets 3.0 では, ビルドオプションにより, 文字列の内部表現が UTF-32, UTF-16 または UTF-8 のいずれかになる。Windows では UTF-16, UNIX (Linux) では UTF-32 または UTF-8.
アプリケーション開発者は、ポータブルにするためには, 3つとも対応する必要がある。
UTF-16 | 一つの code point が, 1つまたは 2つの wchar (code unit) に なる. |
UTF-8 | 一つの code point (21bit) が 1-4 バイト (code unit) になる. |
必要な場所では、次のようにして判定しなければならない。wchar_t
の大きさは、WCHAR_MAX
マクロで判定するのがもっともポータブルだろう。
wxUSE_UNICODE_WCHAR
マクロは、定義される・未定義ではなく、1 or 0 なので、#if
を使う。wxUSE_UNICODE_WCHAR
マクロが 0 の場合, wxUSE_UNICODE_UTF8
マクロが有効になる (排他なので片方だけテストでOK)。
サンプルプログラムを書いてみる。
まず, バイト列から wxString
インスタンスを作るには, FromUTF8()
を使う.
Unicode 文字列を扱う場合, データベースに格納する直前に正規化するのがセオリー. しかし, wxString
は Unicode 特有の処理がほぼできないので、ICU と組み合わせる.
正規化はnormalize()
呼び出しだけなのに, 行ったり来たりが面倒。ヘルパー関数を作ったりするんだろう。
Makefile はこんな感じ.
CXX = gcc CXXFLAGS = -Wall `wx-config --cflags` `pkg-config --cflags icu-uc icu-io` LDFLAGS = `wx-config --libs` `pkg-config --libs icu-uc icu-io` -lstdc++ wx3-string: wx3-string.o wx3-string.o: wx3-string.cc