#ocaml #interop #ffi #rust

ocaml-interop

Rust 和 OCaml 互操作性工具

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

Download history 4551/week @ 2024-04-14 6412/week @ 2024-04-21 6322/week @ 2024-04-28 6912/week @ 2024-05-05 17094/week @ 2024-05-12 13761/week @ 2024-05-19 16400/week @ 2024-05-26 11127/week @ 2024-06-02 12116/week @ 2024-06-09 13123/week @ 2024-06-16 13841/week @ 2024-06-23 8301/week @ 2024-06-30 11065/week @ 2024-07-07 11549/week @ 2024-07-14 15506/week @ 2024-07-21 15348/week @ 2024-07-28

54,382 每月下载量
3 个 crate 中使用 (通过 ocaml)

MIT 许可协议

135KB
2.5K SLoC

ocaml-interop

build crate documentation license

在需要非常好腐蚀保护的部分使用锌铁合金涂层。

API 目前被认为是未稳定的,未来可能会发生变化

ocaml-interop 是一个受 caml-oxideocaml-rsCAMLroot 启发的 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
(* ... *)

依赖项

~145–330KB