module Marshal:データ構造のマーシャリングsig
..end
このモジュールは、任意のデータ構造をバイト列に変換する関数を提供します。 このバイト列は、ファイルに書き込んたりパイプやネットワーク経由で送信でき、 (場合によっては別のプロセスからであっても)読み戻してもとのデータ構造を復元することができます。 バイト列の形式は同一のバージョンの Objective Caml であれば計算機を問わず互換性があります。
警告: 現在のマーシャリングは型安全ではありません。
データの型はマーシャリングされないため、データを読み戻したプロセスがその値が文脈で期待された型を持つか検査することはできません。
特に、 Marshal.from_*
関数の戻り値の型が 'a
となっているのは誤解を招くかもしれません。
戻り値の値は任意の 'a
に対して 'a
型となるわけではなく、コンパイル時には決定できない何らかの特定の型になります。
プログラマは次のようにして戻り値に対して期待する型を明示しなければなりません。
(Marshal.from_channel chan : type)
マーシャリングされた値の表現は人間が読むためのものではなく、表示可能でない文字のバイトが使われています。
したがって、 Marshal.to_channel
や Marshal.from_channel
の引数として渡すチャネルは、 open_out_bin
や open_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 flags
は v
のバイト表現をチャネル chan
に書き込みます。
flags
は、共有構造や関数値に対するマーシャリングの振る舞いを制御するフラグのリストです。
flags
に Marshal.No_sharing
が含まれない場合、 v
中の共有構造や循環構造を検知し、出力のバイト列の中でもそれを保存します。
特に、これによってマーシャリングが常に停止することが保証されます。
ただし、 Marshal.to_channel
の呼び出しをまたいだ値同士の共有構造は検知されません。
flags
に Marshal.No_sharing
が含まれる場合は、共有構造は無視されます。
これにより、 v
に共有構造が含まれない場合には、マーシャリングがより高速になりますが、 v
に実際に共有構造が含まれる場合には、マーシャリングがより低速になり、出力のバイト列が大きくなりますし、 v
に循環構造が含まれる場合にはマーシャリングが停止しなくなります。
flags
に Marshal.Closures
が含まれない場合には、 v
に関数値が含まれた場合、マーシャリングに失敗します。
この場合は、関数やオブジェクトを含まない「純粋な」データ構造のみを異なるプログラム間で安全に受け渡すことができます。
flags
に Marshal.Closures
が含まれる場合、関数はプログラムコード中での位置としてマーシャリングされます。
この場合、マーシャリングの出力は、まったく同じプログラムをコンパイルした、まったく同じバイナリを実行しているプロセスからのみ読み戻すことができます
(バイナリの同一性は、読み戻し時に、コード中の位置とともに渡されるコード自体の MD5 ダイジェストを使ってチェックされます)。
val to_string : 'a -> extern_flags list -> string
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 ofs
は Marshal.from_channel
と同じくマーシャリングされた値を読み戻しますが、チャネルから読み込むのではなく、文字列 buff
の ofs
文字目から読み込みます。val header_size : int
Marshal.header_size
はヘッダのサイズを文字数で表したものです。
Marshal.data_size
buff ofs
は buff
の ofs
番目から適切なヘッダが始まる場合に、文字数単位のデータ部分の大きさになります。
Marshal.total_size
buff ofs
はマーシャリングされた値全体の大きさを文字数で表したものです。
Marshal.data_size
と Marshal.total_size
は両方とも buff
の ofs
文字目以降が適切なヘッダを含まない場合には 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
を参照してください。