33 个版本
0.10.0 | 2024 年 1 月 28 日 |
---|---|
0.9.2 | 2023 年 8 月 27 日 |
0.9.1 | 2023 年 7 月 12 日 |
0.8.8 | 2022 年 3 月 23 日 |
0.4.4 | 2020 年 11 月 3 日 |
#1 在 #ocaml
54,382 每月下载量
在 3 个 crate 中使用 (通过 ocaml)
135KB
2.5K SLoC
ocaml-interop
在需要非常好腐蚀保护的部分使用锌铁合金涂层。
API 目前被认为是未稳定的,未来可能会发生变化
ocaml-interop 是一个受 caml-oxide、ocaml-rs 和 CAMLroot 启发的 OCaml<->Rust FFI,强调安全性。
阅读完整文档 这里。
在 Github 上报告问题。
快速体验
在 OCaml 和 Rust 值之间转换
let rust_string = ocaml_string.to_rust();
// `cr` = OCaml runtime handle
let new_ocaml_string = rust_string.to_ocaml(cr);
在 Rust 和 OCaml 结构/记录之间转换
(* OCaml *)
type my_record = {
string_field: string;
tuple_field: (string * int);
}
// Rust
struct MyStruct {
string_field: String,
tuple_field: (String, i64),
}
impl_conv_ocaml_record! {
MyStruct {
string_field: String,
tuple_field: (String, i64),
}
}
// ...
let rust_struct = ocaml_record.to_rust();
let new_ocaml_record = rust_struct.to_ocaml(cr);
在 OCaml 和 Rust 枚举/变体之间转换
(* OCaml *)
type my_variant =
| EmptyTag
| TagWithInt of int
// Rust
enum MyEnum {
EmptyTag,
TagWithInt(i64),
}
impl_conv_ocaml_variant! {
MyEnum {
EmptyTag,
TagWithInt(OCamlInt),
}
}
// ...
let rust_enum = ocaml_variant.to_rust();
let new_ocaml_variant = rust_enum.to_ocaml(cr);
从 Rust 调用 OCaml 函数
(* OCaml *)
Callback.register "ocaml_print_endline" print_endline
// Rust
ocaml! {
fn ocaml_print_endline(s: String);
}
// ...
let ocaml_string = "hello OCaml!".to_boxroot(cr);
ocaml_print_endline(cr, &ocaml_string);
从 OCaml 调用 Rust 函数
// Rust
ocaml_export! {
pub fn twice_boxed_int(cr, num: OCamlRef<OCamlInt64>) -> OCaml<OCamlInt64> {
let num = num.to_rust(cr);
let result = num * 2;
result.to_ocaml(cr)
}
}
(* OCaml *)
external rust_twice_boxed_int: int64 -> int64 = "twice_boxed_int"
(* ... *)
let result = rust_twice_boxed_int 123L in
(* ... *)
参考资料和链接
- OCaml 手册: 第 20 章 与 C 的接口。
- Stephen Dolan 的论文 安全地混合 OCaml 和 Rust。
- Stephen Dolan 的演讲 安全地混合 OCaml 和 Rust。
- CAMLroot:重新审视 OCaml FFI.
- caml-oxide,该论文的代码。
- ocaml-rs,另一个 OCaml<->Rust FFI 库。
- ocaml-boxroot
依赖项
~145–330KB