Skip to content

Instantly share code, notes, and snippets.

@bjjb
Last active September 5, 2022 14:56
Show Gist options
  • Save bjjb/3ebf6746d34d2c728eef650ff536be3c to your computer and use it in GitHub Desktop.
Save bjjb/3ebf6746d34d2c728eef650ff536be3c to your computer and use it in GitHub Desktop.
Calling Rust from Crystal

Demonstrates how to link Rust code in Crystal (on MacOS).

See the Makefile; the Rust crate is built as a dylib, and the Crystal code then uses the linked library. Fairly simple.

Following both Rust and Crystal conventions, lib.rs and foo.cr need to be in a src/ directory; everything else is in the root.

# Makefile
lib = target/debug/foo.dylib
app = bin/foo
all: $(app)
$(lib): src/lib.rs Cargo.toml
cargo build
$(app): $(lib) src/foo.cr
LIBRARY_PATH=$(PWD)/target/debug:$(LIBRARY_PATH) shards build
clean:
rm -r $(app) $(dylib)
[package]
name = "foo"
version = "0.1.0"
edition = "2021"
[lib]
name = "foo"
crate-type = ["dylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@[Link("foo")]
lib R
fun foo() : UInt8*
fun bar() : UInt8*
end
module Foo
def self.foo
String.new(R.foo())
end
def self.bar
String.new(R.bar())
end
end
puts Foo.foo()
puts Foo.bar()
#[no_mangle]
pub extern "C" fn foo() -> *const u8 {
"Foo from Rust\0".as_bytes().as_ptr()
}
#[no_mangle]
pub extern "C" fn bar() -> *const u8 {
"Bar from Rust\0".as_bytes().as_ptr()
}
name: foo
version: 0.1.0
authors:
- bjjb <jj@bjjb.org>
targets:
foo:
main: src/foo.cr
crystal: 1.3.2
license: MIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment