(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