• 追加された行はこの色です。
  • 削除された行はこの色です。
* 概要 [#n5707163]
- 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ビット幅であることに注意。

* Linuxの場合 [#gc0eda21]
** ライブラリ側ファイル [#s85a88f9]
- 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)));
 }
*** コンパイル [#g467c1d9]
- ocamlcにオプション -output-obj -o lib'''name'''.so とすれば共有ライブラリが得られる.
 gcc -I/usr/local/lib/ocaml -c foostub.c
 ocamlc -output-obj -o libfoo.so foo.ml foostub.o

** プログラム本体 [#s0de3411]
- usefoo.c
 #include "foostub.h"
 #include <stdio.h>
 #include <caml/callback.h>
 
 int main(int argc, char** argv) {
   caml_startup(argv);
   printf("%d\n", succ_caml(10));
   return 0;
 }
*** コンパイル [#d73d3ca5]
- 普通の共有ライブラリとしてリンクして実行。
 gcc -I/usr/local/lib/ocaml -o usefoo libfoo.so usefoo.c
*** 実行 [#jcb410e8]
 $ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
 $ ./usefoo
 11

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS