Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


License travis

This is a set of examples on how to embed a Rust library in a Julia package. Interfacing between Julia and Rust library is done using Rust's FFI: the Rust library is exposed as a C dynamic library, and Julia will call Rust functions using ccall.

The build script deps/build.jl uses cargo to build the Rust library deps/RustDylib. Julia bindings to the Rust API are implemented in src/api.jl file.

If the Rust library build is successful during, the file deps/deps.jl is generated, and the package __init__ function will call check_deps to check if the Rust dynamic library is callable. This follows the same convention used by BinaryProvider.jl.


  • Julia v1.0

  • Rust Stable


julia> using Pkg

julia> pkg"add"

julia> Pkg.test("JuliaPackageWithRustDep")

Primitive Type Correspondences

Julia Rust
Int32 i32
Int64 i64
Int64 i64
Float32 f32
Float64 f64
Bool bool

Passing a Julia Owned String to Rust

A Julia String is converted to a Cstring and passed to Rust, which will receive it as a pointer to char.

function rustdylib_inspect_string(s::String)
    ccall((:rustdylib_inspect_string, librustdylib), Cvoid, (Cstring,), s)

In Rust, the pointer to thar *const c_char is converted to a CStr, which is a reference to a C String. From a CStr, you can convert it to a regular &str.

use std::ffi::CStr;
use std::os::raw::c_char;

pub extern fn rustdylib_inspect_string(cstring: *const c_char) {
    let cstr = unsafe { CStr::from_ptr(cstring) };

    match cstr.to_str() {
        Ok(s) => {
            // `s` is a regular `&str`
            println!("Rust read `{:?}`.", s);
        Err(_) => {
            panic!("Couldn't convert foreign Cstring to &str.");

Returning a Rust Owned String to Julia

In this example, the Rust generates a owned string with rustdylib_generate_rust_owned_string and the ownership is transfered to the Julia process.

After being consumed, the Julia process must transfer the ownership back to Rust by calling rustdylib_free_rust_owned_string, to let the memory be freed.

use std::ffi::CString;
use std::os::raw::c_char;

pub extern fn rustdylib_generate_rust_owned_string() -> *mut c_char {
    let rust_string = String::from("The bomb: 💣");
    let cstring = CString::new(rust_string).unwrap();
    cstring.into_raw() // transfers ownership to the Julia process

pub unsafe extern fn rustdylib_free_rust_owned_string(s: *mut c_char) {
    if !s.is_null() {
        drop(CString::from_raw(s)) // retakes ownership of the CString and drop

In the Julia process, the pointer to string is copied to a new String instance using unsafe_string function. Then, Julia asks Rust to free the string.

function rustdylib_free_rust_owned_string(s::Cstring)
    ccall((:rustdylib_free_rust_owned_string, librustdylib), Cvoid, (Cstring,), s)

function rustdylib_generate_rust_owned_string()
    ccall((:rustdylib_generate_rust_owned_string, librustdylib), Cstring, ())

function read_rust_owned_string() :: String
    cstring = rustdylib_generate_rust_owned_string()
    result = unsafe_string(cstring) # copies the contents of the string
    rustdylib_free_rust_owned_string(cstring) # ask Rust to free the memory
    return result