Skip to content

Instantly share code, notes, and snippets.

@lorepozo
Last active April 16, 2018 06:10
Show Gist options
  • Save lorepozo/00725bde74ab669160faf05a435c1e2d to your computer and use it in GitHub Desktop.
Save lorepozo/00725bde74ab669160faf05a435c1e2d to your computer and use it in GitHub Desktop.
Rust call Ocaml
/target
**/*.rs.bk
*.cmi
*.cmx
*.o
use std::env;
use std::path::Path;
use std::process::Command;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
Command::new("ocamlopt")
.args(&["-output-complete-obj", "mod.ml", "-o"])
.arg(&format!("{}/mod.o", out_dir))
.status()
.expect("ocaml is required");
Command::new("ar")
.args(&["rcs", "libmod.a", "mod.o"])
.current_dir(&Path::new(&out_dir))
.status()
.unwrap();
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static=mod");
}
[package]
name = "caml_from_rust"
version = "0.1.0"
authors = ["Lucas Morales <[email protected]>"]
[dependencies]
raml = "0.1"
[[bin]]
name = "caml_from_rust"
path = "main.rs"
#[macro_use]
extern crate raml;
fn main() {
ocamlthings::initialize_ocaml();
let n = ocamlthings::fib(10);
println!("{}", n);
}
mod ocamlthings {
use std::ptr;
use raml::mlvalues::Value;
use raml::callback::{caml_callback, caml_named_value, caml_startup};
pub fn initialize_ocaml() {
let args: &mut [u8] = &mut [];
let ptr = args.as_mut_ptr();
let argv = ptr as *mut *mut u8;
unsafe {
caml_startup(argv);
}
}
pub fn fib(n: i32) -> i32 {
static FIB_NAME: &str = "fib\0";
static mut FIB_CLOSURE: *const Value = ptr::null();
unsafe {
if FIB_CLOSURE.is_null() {
FIB_CLOSURE = caml_named_value(FIB_NAME.as_ptr());
};
int_val!(caml_callback(*FIB_CLOSURE, val_int!(n))) as i32
}
}
}
let rec fib n = if n < 2 then 1 else fib(n-1) + fib(n-2)
let _ = Callback.register "fib" fib
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment