是否可以将C函数作为回调传给OCaml?

问题描述 投票:0回答:1

我正在研究如何将OCaml TCPIP协议栈集成到我的C++项目中,我已经知道如何从OCaml中调用C,以及从C中调用OCaml。我已经知道如何从OCaml中调用C,从C中调用OCaml,感谢这个答案。OCaml作为C库,hello world的例子。

OCaml将由C++控制,而不是相反。所以,对于TCPIP协议栈,我必须能够发送和接收数据包。我可以很容易地通过C++向TCPIP协议栈发送数据,但是如何接收数据呢?我需要传递一个C函数(回调)作为参数给OCaml,这样当数据到达时,它就会把数据传送过来。这可能吗?

c++ c ocaml
1个回答
3
投票

你需要两个C函数。第一个(wrap_fun 下面的)是从C代码中调用的,它接受一个C回调并返回一个OCaml值,然后你可以把它传给你的OCaml代码。它接受一个 C 回调并返回一个 OCaml 值,然后你可以将其传递给你的 OCaml 代码。第二个 (call_wrapped 以下)从OCaml代码中调用。它接受第一个函数创建的 OCaml 值,并调用存储在其中的回调。

你没有指定任何关于回调的签名,所以下面的代码用于 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);
}

在OCaml方面,它看起来如下。

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"

在OCaml方面,它看起来是这样的: CAMLparam2CAMLreturn 宏在 call_wrapped 只是为了说教而存在。它们可以安全地被移除,因为函数只是实际函数的一个包装器。

© www.soinside.com 2019 - 2024. All rights reserved.