Here’s an example showing how to call a Rust function from Deno:
Compile it to a C dynamic library (libadd.so
on Linux):
rustc --crate-type cdylib add.rs
In C you can write it as:
// add.c
int add(int a, int b) {
return a + b;
}
And compile it:
Calling the library from Deno:
// ffi.ts
// Determine library extension based on
// your OS.
let ext = "";
switch (Deno.build.os) {
case "windows":
ext = "dll";
case "darwin":
ext = "dylib";
break;
case "linux":
ext = "so";
break;
}
const libName = `./libadd.${libSuffix}`;
// Open library and define exported symbols
const dylib = Deno.dlopen(libName, {
"add": { parameters: ["isize", "isize"], result: "isize" },
});
// Call the symbol `add`
const result = dylib.symbols.add(35, 34); // 69
There are many use cases where users might want to run CPU-bound FFI functions in the background without blocking other tasks on the main thread.
As of Deno 1.15, symbols can be marked nonblocking
in Deno.dlopen
. These
function calls will run on a dedicated blocking thread and will return a
Promise
resolving to the desired result
.
Example of executing expensive FFI calls with Deno:
Calling it from Deno:
const library = Deno.dlopen("./sleep.so", {
sleep: {
parameters: ["usize"],
result: "void",
nonblocking: true,
},
});
library.symbols.sleep(500).then(() => console.log("After"));
console.log("Before");
Result:
$ deno run --allow-ffi --unstable unblocking_ffi.ts
Before
After
- [1]
buffer
type is only accepted in symbol parameters.
is an external tool to simplify glue code generation of Deno FFI libraries written in Rust.
It is similar to wasm-bindgen
in
the Rust WASM ecosystem.
Here’s an example showing its usage:
Run deno_bindgen
to generate bindings. You can now directly import them into
Deno:
// mul.ts
import { mul } from "./bindings/bindings.ts";
mul({ a: 10, b: 2 }); // 20
Any issues related to deno_bindgen
should be reported at