A safe and ergonomic wrapper around Wolfram LibraryLink.
Wolfram LibraryLink is an interface for dynamic libraries that can be dynamically loaded by the Wolfram Language. This crate provides idiomatic Rust bindings around the lower-level LibraryLink C interface.
Features:
- Call Rust functions from Wolfram code.
- Pass data efficiently between Rust and Wolfram code using native data types
like [
NumericArray] and [Image]. - Pass arbitrary expressions between Rust and Wolfram code using
[
Expr][struct@crate::Expr] and the [#[export(wstp)]][crate::export#exportwstp] macro. - Generate asynchronous events handled by the Wolfram Language, using an [
AsyncTaskObject] background thread.
What is Wolfram LibraryLink?
Wolfram LibraryLink provides a powerful way to connect external code to the Wolfram Language, enabling high-speed and memory-efficient execution. It does this by allowing dynamic libraries to be directly loaded into the Wolfram Language kernel so that functions in the libraries can be immediately called from the Wolfram Language.
Library function types
The Wolfram LibraryLink interface supports two different types of library function:
- Native functions
- WSTP functions
The two function types differ in how their arguments and return value are passed between the Wolfram Language and the compiled library function.
Native functions pass their values using efficient native data types, like machine sized
integers, floating point numbers, C strings, or [NumericArray]s. Calling a native
function is efficient, but they are unable to pass more complicated values
(like general Wolfram Language expressions).
WSTP functions pass their values using WSTP [Link] objects. A Link object can
be used to pass arbitrary Wolfram Language expressions to or from the library
function. However, WSTP links are less efficient for passing basic numeric arguments.
Examples
Example programs: In addition to the basic example programs show below, the wolfram-library-link repository contains example programs demonstrating the major features of this crate.
Quick Start: The LibraryLink for Rust Quick Start is a complete tutorial covering how to create a new Rust library, compile it, and call into it from the Wolfram Language.
Native functions
Rust functions can be exported for use from the Wolfram Language using the
[#[export]][crate::export] macro:
#
Then, after building the Rust code into a dynamic library, the function can be loaded
into the Wolfram Language using LibraryFunctionLoad:
square = LibraryFunctionLoad["<library name>", "square", {Integer}, Integer];
After being loaded, a library function can be called like any other Wolfram Language function:
square[5] (* Returns 25 *)
WSTP Functions
Rust WSTP functions can be exported for use from the Wolfram Language using the
[#[export(wstp)]][crate::export#exportwstp] macro:
#
Documentation
- [How To: Convert Between Rust and Wolfram Types][crate::docs::converting_between_rust_and_wolfram_types]
- [How To: Evaluate Wolfram code from Rust][docs::evaluate_wolfram_code_from_rust]
See the [docs] module for a complete list of available long-form documentation.
Additional Features
Non-primitive native types
Native functions support passing primitive types like [bool], [i64], [f64],
and strings. Additionally, they also support a small number of non-primitive types
that can be used to efficiently pass more complicated data structures between the
Wolfram Langauge and compiled code, without requiring the full generality of using a
WSTP function.
The set of currently supported non-primitive native types includes:
- [
NumericArray] - [
Image] - [
DataStore]
Cooperative computation abort handling
The Wolfram Language supports the ability for the user to abort an in-progress computation, without ending the process and losing their current state. This is accomplished by code that checks if an abort has been triggered — and if so, performs an early return — which is placed at important points in the Wolfram Language kernel evaluation process.
User libraries can cooperatively include abort checking logic in their library using
the [aborted()] function. This enables LibraryLink libraries to provide the same
user experience as built in Wolfram Language functions. LibraryLink libraries that may
perform long computations are especially encouraged to do abort checking within loops
that may run for a long time.
use wolfram_library_link as wll;
if wll::aborted() {
// The user aborted this computation, so it doesn't matter what we return.
panic!("Wolfram abort");
}
Note: The Wolfram Language 'abort' command is not at all related to the
C/Rust [abort()][std::process::abort] function. The abort() function is typically used
when an unrecoverable error occurs, at a point determined by the programmer. The
Wolfram 'abort' command can be issued by the user at any point, and is commonly used
to end long-running computations the user no longer wishes to wait for.
Show backtrace when a panic occurs
WSTP functions will automatically catch any
Rust panics that occur in the wrapped code, and return a Failure object
with the panic message and source file/line number. The failure can optionally include
a backtrace showing the location of the panic.
This is configured by the "LIBRARY_LINK_RUST_BACKTRACE" environment variable. Enable
it by evaluating:
SetEnvironment["LIBRARY_LINK_RUST_BACKTRACE" -> "True"]
Now the error shown when a panic occurs will include a backtrace.
The error message may include more information if the "nightly"
feature of wolfram-library-link is enabled.