Hello everybody,
First of all I'd like to apologize for my english which is so bad but
I'm think that I'll have a few more answers than if I was posting in
french.
I'm trying to pass an matrix of unsigned chars that I have allocated
in C to OCAML.
Some people advised me to use the bigarray library. I seems to be
what I needed so I read the documentation of this lib and of the
module.
Currently I can allocate arrays in ocaml without any problem, I can
allocate bigarrays in C, I can give the C allocated bigarray to OCAML
but the values that I gived to the fields of the matrix don't pass.
Two examples :
===================== TEST1 ======================
test.c
----
#include <caml/mlvalues.h>
#include <caml/bigarray.h>
#include <stdio.h>
value caml_get_c_array(void)
{
long dims[2];
unsigned char **my_c_array;
/* I allocate my matrix */
my_c_array = malloc(sizeof (unsigned char *) * 2);
my_c_array[0] = malloc(sizeof (unsigned char) * 2);
my_c_array[1] = malloc(sizeof (unsigned char) * 2);
/* I give some values */
my_c_array[0][0] = 3;
my_c_array[0][1] = 4;
my_c_array[1][0] = 5;
my_c_array[1][1] = 6;
dims[0] = 2;
dims[1] = 2;
/* I return the bigarray */
return alloc_bigarray(BIGARRAY_UINT8 | BIGARRAY_C_LAYOUT, 2,
my_c_array, dims);
}
test.ml
----
external take_matrix : unit -> (int, Bigarray.int8_unsigned_elt,
Bigarray.c_layout) Bigarray.Array2.t = "caml_get_c_array";;
let _ =
let m = take_matrix () in
print_int m.{0, 0};
print_string " ";
print_int m.{0, 1};
print_newline ();
print_int m.{1, 0};
print_string " ";
print_int m.{1, 1};
print_newline ();
===
$ cd ../C/ && gcc -W -Wall -ansi -pedantic -I /usr/local/lib/ocaml -c
test.c && cd ../OCAML/ && ocamlc -custom bigarray.cma ../C/test.o
test.ml && ./a.out
208 208
6 8
As you can see these values are no exactly the ones that I gave in
test.c, but if I add :
m.{0, 0} <- 5;
print_int m.{0, 0};
It displays the 5, so I infer that the C array has been allocated.
Example 2 :
===================== TEST2 ======================
test2.c
----
#include <caml/mlvalues.h>
#include <caml/bigarray.h>
#include <stdio.h>
/* this function only displays the bigarray */
value display(value m)
{
unsigned char **t;
t = Data_bigarray_val(m);
printf("-- C --n");
printf("height : %ld, width %ldn", Bigarray_val(m)->dim[0],
Bigarray_val(m)->dim[1]);
printf("%d %dn", t[0][0], t[0][1]);
printf("%d %dn", t[1][0], t[1][1]);
return Val_unit;
}
/* this one multiplies each field by two */
value bytwo(value m)
{
unsigned char **t;
t = Data_bigarray_val(m);
t[0][0] = t[0][0] * 2;
t[0][1] = t[0][1] * 2;
t[1][0] = t[1][0] * 2;
t[1][1] = t[1][1] * 2;
return Val_unit;
}
test2.ml
----
external print_bigarray : (int, Bigarray.int8_unsigned_elt,
Bigarray.c_layout) Bigarray.Array2.t -> unit = "display"
external double_bigarray : (int, Bigarray.int8_unsigned_elt,
Bigarray.c_layout) Bigarray.Array2.t -> unit = "pardeux"
let _ =
let m = Bigarray.Array2.create Bigarray.int8_unsigned
Bigarray.c_layout 2 2 in (* I create my matrix *)
m.{0, 0} <- 1; (* I give some values *)
m.{0, 1} <- 2;
m.{1, 0} <- 3;
m.{1, 1} <- 4;
print_string "-- OCAML --n"; (* I display the values of the
matrix *)
print_int m.{0, 0};
print_string " ";
print_int m.{0, 1};
print_newline ();
print_int m.{1, 0};
print_string " ";
print_int m.{1, 1};
print_newline ();
print_bigarray m; (* I ask to a C function to display the values
of the matrix *)
double_bigarray m; (* I ask to a C function to multiply the
values by two *)
print_string "-- OCAML --n"; (* I print the values of the matrix
to be sure that I can see in OCAML the C modifications *)
print_int m.{0, 0};
print_string " ";
print_int m.{0, 1};
print_newline ();
print_int m.{1, 0};
print_string " ";
print_int m.{1, 1};
print_newline ();
print_bigarray m; (* I ask to C to printf the matrix *)
===
$ cd ../C/ && gcc -W -Wall -ansi -pedantic -I /usr/local/lib/ocaml -c
test2.c && cd ../OCAML/ && ocamlc -custom bigarray.cma ../C/test2.o
test2.ml && ./a.out
-- OCAML --
1 2
3 4
-- C --
height : 2, width 2
Segfault
As you can see no problem from OCAML, the given values are correctly
displayed but the matrix is no passed to C. But I can access to the
fields that give the dimensions of the matrix.
============
My objective is to do what I tryied to in the first example, to
allocate a matrix en C and give the values of the matrix in C and
then give it to OCAML so I can make some modifications with OCAML.
Does anyone know how I can do it ?
If you need more informations, or you have any question, don't be shy
and ask, I'll answer as soon as possible.
Thanks in advance.
--
Stefano Ballabeni
.