アプリケーションに仮想UTF-8環境を提供するmingwで使用するラッパーレイヤーを作成しています。ファイル名を処理する関数は、UTF-8から変換し、対応する「_w」関数などを呼び出すラッパーです。私が遭遇した大きな問題は、Windowswchar_t
が16ビットであるということです。
ファイルシステム操作の場合、それは大したことではありません。UTF-8とUTF-16の間で変換するだけで、すべてが機能します。ただし、標準のCマルチバイト/ワイド文字変換APIでは、multi-wchar_t文字は使用できません。
可能な解決策:
- UTF-8の代わりにCESU-8環境を提供します。私はこれが本当に好きではありません。
- 簡単な方法でBMPのみをサポートしてください。長さ4のUTF-8シーケンスを無効として扱います。
- ラッパーを拡張して、mingwを置き換え
wchar_t
、typedef int32_t wchar_t;
処理しWCHAR
、wchar_t
異なるものにします。これは面倒ですが、クリーンなPOSIXタイプの環境を期待し、wchar_t
Windows-APIの目的には使用しないアプリを移植するのに理想的かもしれません。 - 次のハック:
mbrtowc
wchar_t
4バイトのUTF-8文字の最初の3バイトを読み取った後、上位サロゲートに対応するを出力し、残りの状態をmbstate_t
オブジェクトに保持します。次のバイトを受信すると、それを保存された状態と組み合わせて、下位サロゲートを出力します。最後のバイトが無効になると、-1が返され(EILSEQを使用)、1つのサロゲートが出力ストリームに含まれます(不良...)。
wcrtomb
上位サロゲートを処理するときにUTF-8の最初の2バイトを出力し、残りの状態をmbstate_t
オブジェクトに保存します。その後、下位サロゲートを処理するときに、それを保存された状態と組み合わせて、UTF-8の最後の2バイトを出力します。有効なローサロゲートが受信されない場合、-1が返され(EILSEQを使用)、不完全なUTF-8シーケンスが出力ストリームに残ります(不良...)。
このハックのプラス面は、入力が有効である限り機能し、UTF-8文字、つまり可能なファイル名/引数などにアクセスできることです。アプリケーションが処理する必要のあるテキスト。
短所は、ISO Cに厳密に準拠しておらず(wchar_t
文字列をステートフルにすることは許可されていません)、誤った部分出力がすでに書き込まれるまで、不正な形式の文字の検出を遅らせることです。
私はさまざまなオプション、特に提案されたハックについてのフィードバックを探しています:それが合理的かどうか、短所が重大なエラーを引き起こす可能性があるかどうか、そしてスキームを妨げる可能性のある他の短所があるかどうか完全に機能します。また、私が考えていなかった他の可能な解決策を聞いてうれしいです。