163: iconvの引数のコンパイルエラー(2)


最新状況

タイトル iconvの引数のコンパイルエラー(2)
状態 完了
カテゴリ バグ
作成日時 2010-07-10 16:17:06
最終更新日時 2010-07-12 09:18:42

履歴

1 | 2010-07-10 16:17:06 | 提案
shinshin319 at yahoo.co.jp
前回の『137: iconvの引数のコンパイルエラー』についてです。
http://onscripter.sourceforge.jp/cgi-bin/kagemai/guest.cgi?action=view_report&id=137&project=onscripter

解決策がSDLにありました。
SDL-1.2.13/src/stdlib/SDL_iconv.c
によると

/* Depending on which standard the iconv() was implemented with,
   iconv() may or may not use const char ** for the inbuf param.
   If we get this wrong, it's just a warning, so no big deal.
*/
#if defined(_XGP6) || \
    defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2))
#define ICONV_INBUF_NONCONST
#endif

#ifdef ICONV_INBUF_NONCONST
	retCode = iconv(cd, (char **)inbuf, inbytesleft, outbuf, outbytesleft);
#else
	retCode = iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft);
#endif

のように判別できるそうです。

このようにSDL側で実装されているので
iconvではなくSDL_iconvを使うように修正すればいいのかなと思います。
iconv_t, iconv_open, iconv_close, iconvを
SDL_iconv_t, SDL_iconv_open, SDL_iconv_close, SDL_iconvに。

秋月かたね

2 | 2010-07-10 16:54:55 | 提案
shinshin319 at yahoo.co.jp
しかし、iconvが有効になっていないSDLでSDL_iconvを使うと
iconvではなくSDL独自のものを使うため、SJISに対応していなくて
正常に変換できないおそれがあると思います。

3 | 2010-07-11 12:04:42 | 受付済
ogapee at aqua.dti2.ne.jp
ご報告ありがとうございます。

昔は無かったと思うのですが、最近の SDL にはこんな便利な関数が追加されていたのです
ね。


これを機にあらためて UTF-8 について調べてみたところ、実は、UTF-16 から UTF-8 への
変換は簡単に計算できることが分かりました。
http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm

ONScripter では、SDL_ttf を利用して文字描画を行うために、SJIS から UTF-16 への変
換はすでに変換表を使って自前で行っています。

そこで、SJIS → 変換表 → UTF-16 → 計算 → UTF-8 とすることで、iconv を使わずに 
SJIS から UTF-8 への変換を実現することにしました。

もしかしたら Big Endian の環境ではうまくいっていない可能性もあるので、テストして
いただければ幸いです。

4 | 2010-07-11 12:41:44 | 受付済
shinshin319 at yahoo.co.jp
私のPowerPC G4を搭載したiMacは、現在は動作していないのです。
それでビッグエンディアン環境での動作テストができないのです。
申し訳ありません。

5 | 2010-07-11 21:48:06 | 受付済
tmkk at smoug.net
convertFromSJISToUTF8の実装にエンディアン依存ではない誤りがあり、文字が正常に変換
できないようです。コンパイラ依存かもしれません。

src_bufは符号付きなので、1バイトずつ読んでorを取る際に符号拡張されてしまい、
0x80を超える場合に上位バイトが0xffになってしまうのが原因のようです。添付のパッチ
のような修正を施すと正常になります。

この問題を修正したところ、Big Endianな環境でも問題なく動作しています。
DirectReader.cpp.diff (text/plain, 487 bytes) [表示] [ダウンロード]

6 | 2010-07-12 03:24:57 | 修正済
ogapee at aqua.dti2.ne.jp
パッチありがとうございます。
若干変更して取り入れさせていただきました。

20100711a 以降で修正済みです。


おっしゃるとおり、このパッチは Endian に関係なく必要になるはずです。

Android でしか試していませんでしたが、調べてみたところ、Android では以下のように
符合拡張されず暗黙的に src_buf を unsigned char* でキャストしてから代入するような
挙動になります。Little Endian な環境の gcc-4.4.4 on Linux だと符合拡張してから代
入されます。 

*src_buf = 0x80;
unsigned short index = *src_buf++;
Android: index is 0x80
Linux: index is 0xff80

7 | 2010-07-12 08:49:36 | 修正済
shinshin319 at yahoo.co.jp
char型はx86等一般的にsigned char型だと思われますが
Androidに限らずARMのgccではchar型はunsigned char型のようです。
そのため、他のプログラムでは-fsigned-charをつけてコンパイルしないと
文字化けしたりしてうまく動作しないということがありました。

8 | 2010-07-12 09:18:42 | 完了
ogapee at aqua.dti2.ne.jp
なるほど!そうだったのですか。
知りませんでした。
補足ありがとうございます。

これですっきりしました。

それでは、本報告も完了とさせていただきます。

[リプライをつける]
Bug Tracking System 影舞 0.8.8
Powered by Ruby 1.8.7