C や Fortran のコードと Caml のコードを結びつける( 18 章「C と Objective Caml のインタフェース」で述べられています) C のスタブコードは、次のようにして big array を利用することができます。
もし v が big array を表す Caml の値だとすると、Data_bigarray_val(v) と いう式は配列のデータ部分へのポインタを返します。このポインタは void 型 で、適切な C の型にキャストすることができます。(例えば double [], char [][10], などなど)
Caml の big array の様々な情報は、C で次のように得ることができます。
C の式 | 返る値 |
---|---|
Bigarray_val(v)->num_dims | 次元の数 |
Bigarray_val(v)->dim[i] | i番目の次元 |
Bigarray_val(v)->flags & BIGARRAY_KIND_MASK | 配列の要素の種類 |
配列の要素の種類は、次の定数のうちのどれかです。
定数 | 要素の種類 |
---|---|
BIGARRAY_FLOAT32 | 32ビットの単精度浮動小数点数 |
BIGARRAY_FLOAT64 | 64ビットの倍精度浮動小数点数 |
BIGARRAY_SINT8 | 8ビット符号付き整数 |
BIGARRAY_UINT8 | 8ビット符号なし整数 |
BIGARRAY_SINT16 | 16ビット符号付き整数 |
BIGARRAY_UINT16 | 16ビット符号なし整数 |
BIGARRAY_INT32 | 32ビット符号付き整数 |
BIGARRAY_INT64 | 64ビット符号付き整数 |
BIGARRAY_CAML_INT | 31ビットか63ビットの符号付き整数 |
BIGARRAY_NATIVE_INT | 32ビットか64ビットの(プラットフォームネイティブな)整数 |
以下は、2次元の big array を C と Fortran の関数に渡す例です。
extern void my_c_function(double * data, int dimx, int dimy); extern void my_fortran_function_(double * data, int * dimx, int * dimy); value caml_stub(value bigarray) { int dimx = Bigarray_val(bigarray)->dim[0]; int dimy = Bigarray_val(bigarray)->dim[1]; /* C passes scalar parameters by value */ my_c_function(Data_bigarray_val(bigarray), dimx, dimy); /* Fortran passes all parameters by reference */ my_fortran_function_(Data_bigarray_val(bigarray), &dimx, &dimy); return Val_unit; }
既にメモリ領域が割り当てられた C や Fortran の配列へのポインタ p は、 alloc_bigarray や alloc_bigarray_dims 関数を使って Caml の世界に持って 帰ることができます。
alloc_bigarray(kind | layout, numdims,p, dims)
p で示されるデータをラップして Caml の big array として返します。 kind は配列の要素の種類です(上で述べた BIGARRAY_ のうちのひとつ)。 layout には、C の配列なのか(BIGARRAY_C_LAYOUT)、Fortran の配列なのか (BIGARRAY_FORTRAN_LAYOUT)を指定します。numdims は配列の次元の数です。 dmis は numdims の長さの整数の配列で、それぞれの配列のサイズを表します。
alloc_bigarray_dims(kind | layout, numdims, p, (long) dim1, (long) dim2, …, (long) dimnumdims)
> alloc_bigarray と同じですが、それぞれの次元の配列のサイズを配列として 渡すのではなく、関数呼び出しの引数に直接追加されています。
以下は、静的に割り当てられた C と Fortran の配列をどうやって Caml から扱えるようにするかを表した例です。
extern long my_c_array[100][200]; extern float my_fortran_array_[300][400]; value caml_get_c_array(value unit) { long dims[2]; dims[0] = 100; dims[1] = 200; return alloc_bigarray(BIGARRAY_NATIVE_INT | BIGARRAY_C_LAYOUT, 2, my_c_array, dims); } value caml_get_fortran_array(value unit) { return alloc_bigarray_dims(BIGARRAY_FLOAT32 | BIGARRAY_FORTRAN_LAYOUT, 2, my_fortran_array_, 300L, 400L); }