是否可以将 C 函数作为回调传递给 OCaml?
Is it posible to pass a C function as callback to OCaml?
我正在研究如何将 OCaml TCP/IP 堆栈集成到我的 C++ 项目中。由于这个答案,我已经知道如何从 OCaml 调用 C 和从 C 调用 OCaml:
OCaml 将由 C++ 控制,而不是相反。因此,对于 TCP/IP 堆栈,我必须能够发送和接收数据包。我可以很容易地通过C++向TCP/IP栈发送数据,但是如何接收呢?我需要将 C 函数(回调)作为参数传递给 OCaml,以便它在数据到达时传递数据。可能吗?
为此你需要两个 C 函数。第一个(下面的 wrap_fun
)是从 C 代码调用的。它需要一个 C 回调和 returns 一个 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"
call_wrapped
中的 CAMLparam2
和 CAMLreturn
宏仅用于教学目的。可以安全地删除它们,因为函数只是实际函数的包装器。
我正在研究如何将 OCaml TCP/IP 堆栈集成到我的 C++ 项目中。由于这个答案,我已经知道如何从 OCaml 调用 C 和从 C 调用 OCaml:
OCaml 将由 C++ 控制,而不是相反。因此,对于 TCP/IP 堆栈,我必须能够发送和接收数据包。我可以很容易地通过C++向TCP/IP栈发送数据,但是如何接收呢?我需要将 C 函数(回调)作为参数传递给 OCaml,以便它在数据到达时传递数据。可能吗?
为此你需要两个 C 函数。第一个(下面的 wrap_fun
)是从 C 代码调用的。它需要一个 C 回调和 returns 一个 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"
call_wrapped
中的 CAMLparam2
和 CAMLreturn
宏仅用于教学目的。可以安全地删除它们,因为函数只是实际函数的包装器。