Is it posible to pass a C function as callback to OCaml?

一世执手 提交于 2020-08-09 09:11:19

问题


I'm studying on how to integrate an OCaml TCP/IP stack into my C++ project. I already know how to call C from OCaml and call OCaml from C thanks to this answer: OCaml as C library, hello world example

The OCaml will be controlled by C++, not the other way around. So, for a TCP/IP stack, I must be able to send and receive packets. I can easily send data to the TCP/IP stack through C++, but how to receive it? I need to pass a C function (a callback) as a parameter to OCaml so it delivers the data when it arrives. Is it possible?


回答1:


You need two C functions for that. The first one (wrap_fun below) is called from C code. It takes a C callback and returns an OCaml value that you can then pass to your OCaml code. The second one (call_wrapped below) is called from the OCaml code. It takes an OCaml value created by the first function and calls the callback stored into it.

You did not specify anything about the signature of your callback, so the code below goes for value(value).

#include <caml/alloc.h>
#include <caml/memory.h>
#include <caml/mlvalues.h>

typedef value (*cb)(value);

value wrap_fun(cb f) {
  value v = caml_alloc_small(1, Abstract_tag);
  Field(v, 0) = (value)f;
  return v;
}

value call_wrapped(value f, value x) {
  CAMLparam2(f, x);
  cb g = (cb)Field(f, 0);
  value z = g(x);
  CAMLreturn(z);
}

On the OCaml side, it looks as follows:

external call_wrapped : ('a, 'b) wrapped_fun -> 'a -> 'b  = "call_wrapped"

let foo f x =
  let y = x + 1 in
  let z = call_wrapped f y in
  z ^ "a"

The CAMLparam2 and CAMLreturn macros in call_wrapped are just there for didactic purpose. They can safely be removed, since the function is just a wrapper to the actual function.



来源:https://stackoverflow.com/questions/61537623/is-it-posible-to-pass-a-c-function-as-callback-to-ocaml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!