Expand description

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 and the #[export(wstp)] macro.
  • Generate asynchronous events handled by the Wolfram Language, using an AsyncTaskObject background thread.

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.

    — Wolfram LibraryLink User Guide

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 NumericArrays. 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] macro:

use wolfram_library_link::export;

#[export]
fn square(x: i64) -> i64 {
    x * x
}

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)] macro:

use wolfram_library_link::{export, wstp::Link};

#[export(wstp)]
fn square(link: &mut Link) {
    // WSTP function arguments are passed as a List expression: {...}
    let arg_count = link.test_head("System`List").unwrap();

    // Get that the argument list contains a single element.
    if arg_count != 1 {
        panic!("square: expected one argument")
    }

    // Check that the argument is an integer, and get it's value.
    let x: i64 = link.get_i64().expect("expected Integer argument");

    // Write the return value.
    link.put_i64(x * x).unwrap();
}

Documentation

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:

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() 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.

Re-exports

Modules

  • Documentation articles about the usage of wolfram-library-link.
  • Efficient and ergonomic representation of Wolfram expressions in Rust.
  • Managed expressions.
  • Lazy bindings to Wolfram Runtime Library (RTL) functions.

Macros

  • Generate and export a “loader” function, which returns an Association containing the names and loaded forms of all functions exported by this library.

Structs

Enums

Traits

Functions

Attribute Macros

  • Export the specified functions as native LibraryLink functions.
  • Designate an initialization function to run when this library is loaded via Wolfram LibraryLink.