2009/02/05

文字列処理の変更

このところ、自分で使うためのソフトいくつか作っていたのだが、そろそろ「主筆」の開発に戻ることにした。

かなり前にもここに書いた覚えがあるが、今現在取り組んでいるのは、「主筆」内部で取り扱う文字列をワイドバイト文字列で統一する作業である。

「主筆」内部では、基本的には文字列はワイドバイト文字列(すなわちwchar_tの配列ないしstd::wstring)で取り扱うようにしているのだが、一部そうでない部分がある。正確に言えば、ファイル名は全てマルチバイト文字列(すなわちcharの配列ないしstd::string)で取り扱っている。

だが、移植性や互換性といったプログラムの品質といったものを考えた場合、文字列は全てワイドバイト文字列で取り扱うのが正しいように思われる。しかし、Solarisはシステムコールやライブラリ関数がワイドバイト文字列に対応していないことが多く、酷く厄介である。

Windowsの場合、ほとんど全ての関数に対して、マルチバイト文字列(実装上はShift-JIS)を取り扱うバージョンと、ワイドバイト文字列(実装上はUCS-2、すなわちサロゲートペアの無い16ビットのUnicode)をおり扱うバージョンとか用意されており、かつ、それらをコンパイル時に切り替えられるようにするたの関数とか用意されている。

つまり、Windows上でプログラムを作る場合は、文字列は全てCStringないしTCHAR型配列として実装すればよく、ライブラリの非互換性などの問題は時々気にしてやればいいだけである。しかしSolarisの場合、外部の関数を呼ぶ場合にはほとんど全ての場合において、文字列のエンコードをマルチバイト文字列に変換してやらなければならない。

例えば、ファイルを開くためにfopen関数を呼ぶにしても、ワイドバイト文字列のバージョンは用意されていないため、ファイル名をマルチバイト文字列に変換してからファイルを開くということをしてやらなければならない。

面倒なことこの上ない。しかも、処理が遅くなりそうで気に入らない。だから「主筆」では、ファイル名などの一部のデータはマルチバイト文字列のままで処理するようにしていた。しかし最近になって、ワイドバイト文字列とマルチバイト文字列の混在による複雑さが手に負えなくなってきたから、面倒さはあるとはいえ全てワイドバイト文字列で統一することにしたのだ。

プログラム内部の処理方式を変えたからといって、基本的には外部に影響を及ぼすことはない。元より、ユーザがマウスとキーボードで操作するだけのソフトである。文字列の形式など問題とはなり得ない。しかし、今回の対応を行うことにより、一部分どうしても影響を受けざるを得ないものがある。

それはプラグイン関数のインタフェースである。プラグイン関数では引数にファイル名を受け取るものがあるが、そのファイル名がマルチバイト文字列(すなわちconst char*)になっているのである。

互換性のためにはconst char*の引数を受け取る関数を変更するわけにはいかないが、逆に手つかずのままにしておくこともできない。だとすると、const wchar_t*を受け取るバージョンの関数を新たに作って提供しなければならないことになる。

どうにも面倒だが、まぁ、仕方あるまい。

0 件のコメント: