C や Fortran のコードと Caml のインタフェースとなる C のスタブコードについては 18 章「C と Objective Caml のインタフェース」 で述べました。 そこから bigarray を利用するには次のようにします。
v が bigarray を表す Caml の value であるとき、式 Data_bigarray_val( は bigarray のデータ部分へのポインタを返します。
このポインタは void * 型で、 double [] や char [][10] といった適切な C の配列の型へとキャストすることができます。
v)
次のようにして Caml の bigarray の情報を C から取り出すことができます。
| C の式 | 戻り値 |
|---|---|
Bigarray_val( |
次元数 |
Bigarray_val( |
i 次元目 |
Bigarray_val( |
配列の要素の種類 |
配列の要素の種類は、次の定数のうちのいずかです。
| 定数 | 要素の種類 |
|---|---|
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;
}
既にメモリ領域が割り当てられた C や Fortran の配列へのポインタ p を
alloc_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);
}