JuliaPackageWithRustDep.jl
Example of a Julia Package with Rust dependency.
Install / Use
/learn @felipenoris/JuliaPackageWithRustDep.jlREADME
JuliaPackageWithRustDep.jl
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 Pkg.build, 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.
Requirements
-
Julia v1.0
-
Rust Stable
Installation
julia> using Pkg
julia> pkg"add https://github.com/felipenoris/JuliaPackageWithRustDep.jl.git"
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)
end
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;
#[no_mangle]
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;
#[no_mangle]
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
}
#[no_mangle]
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)
end
function rustdylib_generate_rust_owned_string()
ccall((:rustdylib_generate_rust_owned_string, librustdylib), Cstring, ())
end
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
end
Resources
Related Skills
node-connect
351.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
110.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
351.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
351.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
