我正在研究如何将OCaml TCPIP协议栈集成到我的C++项目中,我已经知道如何从OCaml中调用C,以及从C中调用OCaml。我已经知道如何从OCaml中调用C,从C中调用OCaml,感谢这个答案。OCaml作为C库,hello world的例子。
OCaml将由C++控制,而不是相反。所以,对于TCPIP协议栈,我必须能够发送和接收数据包。我可以很容易地通过C++向TCPIP协议栈发送数据,但是如何接收数据呢?我需要传递一个C函数(回调)作为参数给OCaml,这样当数据到达时,它就会把数据传送过来。这可能吗?
你需要两个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方面,它看起来是这样的: CAMLparam2
和 CAMLreturn
宏在 call_wrapped
只是为了说教而存在。它们可以安全地被移除,因为函数只是实际函数的一个包装器。