wchar_t対応版libstdc++
昨日の続きです。
libstdc++のconfigureスクリプトを確認したところ、iconvとlanginfoが動かないと、wchar_t対応にならないようでした。
iconvはGNUのものを使ってもいいのですが、configureの要求するシンボル名と違うことと、実行ファイルを配布する際に別途dllが必要になることから、適当にでっち上げることにしました。
/* iconv.h */ #ifndef ICONV_H #define ICONV_H #include <stddef.h> #if defined(__cplusplus) extern "C" { #endif typedef int iconv_t; iconv_t iconv_open(const char* tocode, const char* fromcode); int iconv_close(iconv_t cd); size_t iconv(iconv_t cd, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft); #if defined(__cplusplus) } // extern "C" #endif #endif /* ICONV_H */
/* iconv.c */ #include "iconv.h" iconv_t iconv_open(const char* tocode, const char* fromcode) { return (iconv_t)-1; } int iconv_close(iconv_t cd) { return 0; } size_t iconv(iconv_t cd, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft) { return (size_t)-1; }
/* langinfo.h */ #ifndef LANGINFO_H #define LANGINFO_H #if defined(__cplusplus) extern "C" { #endif typedef int nl_item; char* nl_langinfo(nl_item item); #if defined(__cplusplus) } // extern "C" #endif #endif /* LANGINFO_H */
/* langinfo.c */ #include "langinfo.h" char* nl_langinfo(nl_item item) { return (char*)""; }
すべてコンパイルとリンクを通すための空実装になっています。
実際には呼ばれないので、これで問題ありません。
これらを、MSYSから
gcc -c iconv.c langinfo.c
ar cr /mingw/lib/libiconv.a iconv.o langinfo.o
cp iconv.h langinfo.h /mingw/include/
として、libstdc++のconfigureをやり直すと、wchar_tサポートが有効になります。
libiconv.aにlanginfo.oを含めているのは、configureスクリプトがlibcとiconvしかリンクしないからです。
こうしてビルドしたlibstdc++を使って、次のプログラムを試してみました。
#include <clocale> #include <iostream> int main() { std::setlocale(LC_ALL, ""); std::wcout << L"\u3042\u3044\u3046\u3048\u304A" << std::endl; }
結果、
あいうえお
を出力できました。
ワイド文字列とマルチバイト文字列の変換ははCの標準関数を使用する実装なので、setlocale()でCの大域ロケールを設定する必要があります。
Boost.Filesystemのwide_testも試してみましたが、問題なく動作しました。
そこそこ使えるのではないかと思います。