[−][src]Macro ocaml_interop::ocaml_export
Defines Rust functions callable from OCaml.
The first argument in these function declarations must be an identifier
to which the OCaml frame GC handle will be bound. Optionally, it can be annotated
with nokeep
when local roots (registered with the keep
method) are not needed.
Arguments and return values must be of type OCaml<T>
, or f64
in the case of unboxed floats.
The return type defaults to unit when omitted.
The body of the function has an implicit ocaml_frame!
wrapper, with the lifetimes of every OCaml<T>
argument bound to the lifetime of the variable bound to the function's OCaml frame GC handle.
Examples
ocaml_export! { fn rust_twice(_gc nokeep, num: OCaml<OCamlInt>) -> OCaml<OCamlInt> { let num: i64 = num.into_rust(); unsafe { OCaml::of_i64(num * 2) } } fn rust_twice_boxed_i32(gc, num: OCaml<OCamlInt32>) -> OCaml<OCamlInt32> { let num: i32 = num.into_rust(); let result = num * 2; ocaml_alloc!(result.to_ocaml(gc)) } fn rust_add_unboxed_floats_noalloc(_gc nokeep, num: f64, num2: f64) -> f64 { num * num2 } fn rust_twice_boxed_float(gc, num: OCaml<f64>) -> OCaml<f64> { let num: f64 = num.into_rust(); let result = num * 2.0; ocaml_alloc!(result.to_ocaml(gc)) } fn rust_increment_ints_list(gc, ints: OCaml<OCamlList<OCamlInt>>) -> OCaml<OCamlList<OCamlInt>> { let mut vec: Vec<i64> = ints.into_rust(); for i in 0..vec.len() { vec[i] += 1; } ocaml_alloc!(vec.to_ocaml(gc)) } fn rust_make_tuple(gc, fst: OCaml<String>, snd: OCaml<OCamlInt>) -> OCaml<(String, OCamlInt)> { let fst: String = fst.into_rust(); let snd: i64 = snd.into_rust(); let tuple = (fst, snd); ocaml_alloc!(tuple.to_ocaml(gc)) } }