Module Marshal


module Marshal: sig .. end
データ構造のマーシャリング

このモジュールは、任意のデータ構造をバイト列に変換する関数を提供します。 このバイト列は、ファイルに書き込んたりパイプやネットワーク経由で送信でき、 (場合によっては別のプロセスからであっても)読み戻してもとのデータ構造を復元することができます。 バイト列の形式は同一のバージョンの Objective Caml であれば計算機を問わず互換性があります。

警告: 現在のマーシャリングは型安全ではありません。 データの型はマーシャリングされないため、データを読み戻したプロセスがその値が文脈で期待された型を持つか検査することはできません。 特に、 Marshal.from_* 関数の戻り値の型が 'a となっているのは誤解を招くかもしれません。 戻り値の値は任意の 'a に対して 'a 型となるわけではなく、コンパイル時には決定できない何らかの特定の型になります。 プログラマは次のようにして戻り値に対して期待する型を明示しなければなりません。

このとき、ファイル中のオブジェクトが指定された型でなかった場合、実行時に何が起こるかはわかりません。

マーシャリングされた値の表現は人間が読むためのものではなく、表示可能でない文字のバイトが使われています。 したがって、 Marshal.to_channelMarshal.from_channel の引数として渡すチャネルは、 open_out_binopen_in_bin を使ってバイナリモードで開かなければなりません。 チャネルをテキストモードで開くと、 Windows のような、テキストチャネルとバイナリチャネルの振る舞いが異なるプラットフォームでは読み戻し時にエラーが起こります。



type extern_flags =
| No_sharing (*共有構造を保存しない*)
| Closures (*クロージャを送る*)
下の Marshal.to_* 関数に渡すフラグです
val to_channel : out_channel -> 'a -> extern_flags list -> unit
Marshal.to_channel chan v flagsv のバイト表現をチャネル chan に書き込みます。 flags は、共有構造や関数値に対するマーシャリングの振る舞いを制御するフラグのリストです。

flagsMarshal.No_sharing が含まれない場合、 v 中の共有構造や循環構造を検知し、出力のバイト列の中でもそれを保存します。 特に、これによってマーシャリングが常に停止することが保証されます。 ただし、 Marshal.to_channel の呼び出しをまたいだ値同士の共有構造は検知されません。 flagsMarshal.No_sharing が含まれる場合は、共有構造は無視されます。 これにより、 v に共有構造が含まれない場合には、マーシャリングがより高速になりますが、 v に実際に共有構造が含まれる場合には、マーシャリングがより低速になり、出力のバイト列が大きくなりますし、 v に循環構造が含まれる場合にはマーシャリングが停止しなくなります。

flagsMarshal.Closures が含まれない場合には、 v に関数値が含まれた場合、マーシャリングに失敗します。 この場合は、関数やオブジェクトを含まない「純粋な」データ構造のみを異なるプログラム間で安全に受け渡すことができます。 flagsMarshal.Closures が含まれる場合、関数はプログラムコード中での位置としてマーシャリングされます。 この場合、マーシャリングの出力は、まったく同じプログラムをコンパイルした、まったく同じバイナリを実行しているプロセスからのみ読み戻すことができます (バイナリの同一性は、読み戻し時に、コード中の位置とともに渡されるコード自体の MD5 ダイジェストを使ってチェックされます)。

val to_string : 'a -> extern_flags list -> string
Marshal.to_string v flagsv のバイト列表現を格納した文字列を返します。 flags 引数の意味は Marshal.to_channel と同じです。
val to_buffer : string -> int -> int -> 'a -> extern_flags list -> int
Marshal.to_buffer buff ofs len v flags は値 v をマーシャリングし、そのバイト列表現を文字列 buff の、 ofs 文字目から最大 len 文字の範囲に格納します。 この関数は実際に書き込んだ文字数を返します。 v のバイト列表現が len 文字に収まらなかった場合には Failure 例外が発生します。
val from_channel : in_channel -> 'a
Marshal.from_channel chan はチャネル chan から、 Marshal.to_* 関数の出力した値のバイト表現を読み込み、それに対応する値を再構成して返します。
val from_string : string -> int -> 'a
Marshal.from_string buff ofsMarshal.from_channel と同じくマーシャリングされた値を読み戻しますが、チャネルから読み込むのではなく、文字列 buffofs 文字目から読み込みます。
val header_size : int
マーシャリングされた値のバイト表現は固定長のヘッダと可変長のデータ部分から構成されます。 データ部分の大きさはヘッダに格納されています。 Marshal.header_size はヘッダのサイズを文字数で表したものです。 Marshal.data_size buff ofsbuffofs 番目から適切なヘッダが始まる場合に、文字数単位のデータ部分の大きさになります。 Marshal.total_size buff ofs はマーシャリングされた値全体の大きさを文字数で表したものです。 Marshal.data_sizeMarshal.total_size は両方とも buffofs 文字目以降が適切なヘッダを含まない場合には Failure 例外を発生させます。

マーシャリングされた値のバイト表現を文字列バッファに読み込むには、まず最初に Marshal.header_size 文字をバッファに読み込み、それから Marshal.data_size を使って残りの長さを特定し、バッファに残りのデータを読み込むのに十分な容量があることを確認した上でデータを読み込み、最後に Marshal.from_string を呼び出して値を読み戻すことになります。

val data_size : string -> int -> int
Marshal.header_size を参照してください。
val total_size : string -> int -> int
Marshal.header_size を参照してください。