OCamlでCの関数を呼んでみよう
30分プログラム、その548。OCamlでCの関数を呼んでみよう。
OCamlバインディングの無いライブラリを使いたいときに必要になるよ。便利かどうかは分からないけど。
Interfacing C with Objective Camlを参考に、階乗計算モジュールを作ってみよう。
Cの関数
OCamlから呼べる関数は、以下の形になる。
CAMLprim value f(value arg1, value arg2, ..., value argN){ ... }
value型とint型の間の変換は、Val_intやInt_valを使う。
int n = Int_val(some_value); value other_value = Val_int(42);
あと、引数CAMLparamNとかを使うとGC的に嬉しいらしい。よく分からないけど。
value bar (value v1, value v2, value v3) { CAMLparam3 (v1, v2, v3); CAMLlocal1 (result); result = alloc (3, 0); ... CAMLreturn (result); }
これらのことを踏まえて、階乗を計算する関数を書くと次のようになる。
#include <caml/mlvalues.h> #include <caml/memory.h> int fact(int n) { int i,r = 1; for(i = 1; i < n ; i++){ r *= i; } return r; } CAMLprim value ml_fact(value n){ CAMLparam1(n); CAMLlocal1(result); result = Val_int(fact(Int_val(n))); CAMLreturn(result); }
コンパイル
$ ocamlc fact.c $ ocamlc -c fact.ml $ ocamlmklib -o fact -oc fact fact.o fact.cmo
これでfact.cmaなどが生成される。ocamlcのかわりにocamloptを使えば、fact.cmxaが生成できる。
さあ、使ってみよう
let _ = print_endline (string_of_int (Fact.fact 10))
$ ocamlc fact.cma main.ml
$ ./a.out
362880