- OCaml特有の話
- OCamlの関数を.soなり.dllなりのシンボルとして直接エクスポートすることはできない。 Cの関数でスタブを書く必要がある。
- OCaml側で, モジュール初期化時に Callback.register 文字列 関数 とすれば 関数を "文字列" という名前でエクスポートできる
- C側では*caml_named_value(文字列)として関数の名前を取得する。
- caml_callbackで関数を呼ぶ
- FFI一般の話
- OCamlランタイムを初期化する必要がある。
- OCamlの値とCの値の相互変換が必要である。下の例ではVal_int(C→OCaml)とInt_val(OCaml→C)を用いている。 OCamlのint型は31ビット幅であることに注意。
- foo.ml
let succ x = x+1
let _ = Callback.register "succ" succ
- foostub.h
int succ_caml(int x);
- foostub.c
#include <caml/mlvalues.h>
#include <caml/callback.h>
#include "foostub.h"
int succ_caml(int x) {
return Int_val(caml_callback(*caml_named_value("succ"), Val_int(x)));
}
$ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
$ ./usefoo
11
- -output-obj foo.o で オブジェクトコードを生成できるのでarで.aを作るなりリンクするなりすればよい