少し前にCDをひとまとめにする方法を書きましたが、
flacでなぜか2GBでとまってしまうという現象の原因がわかりました。
まあ原因そのものは割りとすぐにわかって、fseek/ftellのポインタサイズが
32ビットなのが原因です。約2GB分のオフセットしか表現できないことになります。
通常のオフセットの型は符号付整数longで、コンパイラ依存ですがgccでもVCでも
4byteになります。これを64ビット対応したfseeko64/ftello64にして、
引数のオフセット変数の宣言をlong long型にしてやれば解決なのですが・・・
本来-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64をgccに
渡してあげればいいようなのですが、どうも適用になっていないようです。
なのでconfigureに渡すパラメータとソースファイルの調整が必要になります。
以下、Xiph.orgのflac1.2.1のソースコードとMinGW64の環境で実験しております。
①off_t型の強制書き換え
sys/types.hを見てもらえばわかるように、オフセットのoff_tもしくは
_off_t型はlongで宣言されています。
これをプリプロセスの時点でoff64_tに上書きします。
いちいちソースファイルに#DEFINEを書く必要はありません。
CFLAGSなどにセットするだけで書き換えができます。
長いので自分はスクリプトにしてbashに渡しています。
ちなみに環境はWindows7HomePremium(x64)で、MinGWはx86_64の環境です。
MinGW32(pc-i686)だとtypes.hが微妙に違ったりするので、マクロの構成は
自前で確認してください。
やってることはoff_tの書き換えと、off_tの定義済みフラグを立てることです。
②fseek/ftellのマクロ修正
64ビット対応したfseeko64/ftello64に置き換えるようプリアンブルのマクロを
修正します。基本セットはfseeko/ftelloになっているので
環境に合わせて分岐させればいいです。
ちなみにVC++2010ではfseeki64/ftelli64というメソッドが用意されてます。
記述するとえらいことになるのでpatchを用意しました。
ファイルはこちら
それでもってmakeすると(ウチの環境では)64bitのflacの出来上がりです。
2GBの制限もきれいさっぱりなくなりました。
なぜかnasm通すとエラーになりますが(汗
あ、あと調査の中でわかったのは、fseekのオフセットはフロントエンドに
依存するっぽいです。元のソースのまんまでもライブラリを
直接叩くようなアプリならちゃんと2GB超えても作成できました。
ぶっちゃけWinampなんですが。
VisualC++2010でも無理やりビルドして動作するのを確認はしましたが・・・
いかんせん、疲れた。
0 件のコメント:
コメントを投稿