今回は、PowerPCとx86 CPUのエンディアンの違いによる影響を、実際のソースコードを調べながら検証していきたいと思います。まずは、エンディアンの違いで影響が出るだろうと思われる点を具体的にピックアップしてみます。
・整数フォーマットが反転する(2bytes,4bytes,8bytes整数)
・浮動小数点フォーマットが反転する(4bytes,8Bbytes浮動小数点)
・ネットワークで流れるデータはビッグエンディアンで固定されている
・Excelファイルフォーマットはリトルエンディアンで固定されている
・Photoshop画像フォーマットはビッグエンディアン固定されている
・Quartz 2Dのビットマップ画像はbitmapInfoパラメータで調整される
・TIFF,Exif,Dicomファイルフォーマットは両方が存在 (ヘッダのMMとII表記で区別)
・Font関連リソース(FOND、NFNT、sfnt など)はビッグエンディアン
・OSTypeをストリングとして扱う場合にはエンディアンを考慮する必要がある
・UnicodeはBOMがなければビッグエンディアンとして認識される
・関数を利用してビットテストを実行すると結果が異なる場合がある
・一般リソースデータの入出力はResource Managerがエンディアンを考慮する
・カスタムリソースデータの場合にはエンディアンが考慮されない
・カスタムアップルイベント&ペーストボードデータはビッグエンディアンのまま
まず最初に、エンディアンの違いを考慮すべき典型的な例として、整数フォーマットの反転に対処する例を見てみます。アプリケーションの内部処理で整数を利用している時には何も問題はないですが、固定エンディアンフォーマットで整数や浮動小数点をファイルに保存し、それを別エンディアン環境で読み込み利用しようとした時に問題が生じます。例えば、ビッグエンディアンフォーマット(PowerPC)で保存された初期設定ファイルをリトルエンディアン環境(x86)のHDへ複製してそのまま利用しようとした時などです。
今回の初期設定ファイルは以下の構造体を使い、short整数を128個保存することにします。ファイルのネイティブフォーマットはビッグエンディアン(PowerPC)とします。

最初のgetPrefFSSpec()ルーチンは、ライブラリフォルダ内にあるPreferencesフォルダを探し、そのFSSpecを返します。今回はGetIndString()により、STR#リソースから初期設定ファイル名を得ています。ここではエンディアンの問題は存在しません。

続いて、初期設定の構造体データをファイルから読み込むreadPreferences()ルーチンです。もし初期設定ファイルが無ければ、それを作成してから初期化したデータを書き込みます。よってx86用の実行コードでは、この書き込み処理の直前に、Pref構造体に含まれている整数を反転させる必要があります。それを行っているのがflipPreferences()ルーチンです。ここで注意することは、オリジナルの初期設定構造体(sys_Pref)の整数値を反転させてしまうと、その後の内部処理が正常に行われなくなることです。よって、ここではsys_Prefをtempへ複製し、それを反転させてから書き込むようにしています。

次は、初期設定ファイルを保存(書き出し)するwritePreferences()ルーチンです。処理内容は、readPreferences()の初期設定ファイル新規作成の箇所とほとんど同じです。

以下は、すべての整数配列のエンディアンを反転させるflipPreferences()ルーチンです。2bytes整数の反転にはEndian16_Swap() APIを用いています。このソースをUniversal Binaryとしてコンパイルした場合、#if __LITTLE_ENDIAN__と#endifで挟まれた部分は、PowerPC用の実行ファイルとしてはコンパイルされませんので、PowerPC環境で実行した時には、何も処理しないで素通りすることになります。

初期設定ファイルは、エンディアンの影響を受けないテキストファイルやXMLファイルで保存すべきでしょう(CFPreference APIなどを使う)。しかし、古いアプリケーションに関しては今更手遅れです(笑)。初期設定ファイルが、単体マシンでしか利用されないのなら今回説明した処理は不必要なのですが、Macintoshには「移行アシスタント」という便利なツールがあるおかげで、現在利用している初期設定ファイルも別マシンでそのまま使われる可能性があります。ですから、CPUの種類が異なるマシン環境であると認識したら、初期設定ファイルを再構築する処理か、ファイル読み書きの出入り口で整数や浮動小数点のエンディアンをひっくり返す処理が必要となるわけです。
次回は、Macintosh独自のデータ保存方法「リソース」についてエンディアンの影響を調べてみましょう。例題としてQuickDrawで利用してきたPicture(PICT)構造体を取り上げたいと思います。
copyright 2006 Ottimo, Inc. All rights reserved
無断転載・引用禁止
Contact us: koike@ottimo.co.jp