29.2 Caml-C インタフェースでの bigarray

29.2.1. ヘッダファイル
29.2.2. C や Fortran から Caml の bigarray にアクセスする
29.2.3. C や Fortran の配列を Caml の bigarray に包む

C や Fortran のコードと Caml のインタフェースとなる C のスタブコードについては 18 章「C と Objective Caml のインタフェース で述べました。 そこから bigarray を利用するには次のようにします。

29.2.1 ヘッダファイル

C スタブファイルでは <caml/bigarray.h> をインクルードしなければなりません。 このファイルは以下で述べる関数と定数、マクロを宣言しています。

29.2.2 C や Fortran から Caml の bigarray にアクセスする

v が bigarray を表す Caml の value であるとき、式 Data_bigarray_val(v) は bigarray のデータ部分へのポインタを返します。 このポインタは void * 型で、 double []char [][10] といった適切な C の配列の型へとキャストすることができます。

次のようにして Caml の bigarray の情報を 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 次元の bigarray を 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;
}

29.2.3 C や Fortran の配列を Caml の bigarray に包む

既にメモリ領域が割り当てられた C や Fortran の配列へのポインタ palloc_bigarray 関数や alloc_bigarray_dims 関数を使って Caml の世界に返すことができます。

alloc_bigarray(kind | layout, numdims, p, dims)

p の指すデータを Caml の bligarray に包んだものを返します。 kind は配列の要素の種類です(上の BIGARRAY_* 定数のいずれか)。 layout は C レイアウトの配列に対しては BIGARRAY_C_LAYOUT、 Fortran レイアウトの配列に対しては BIGARRAY_FORTRAN_LAYOUT を指定します。 numdims は配列の次元数です。 dims は長さ 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);
}