A library providing convenient Rust bindings to Matlab's MEX C api.
Rustmex makes writing MEX functions in Rust a bit easier. It convert Matlab types, and
the arguments it provides to mexFunction
into more Rusty types, which can then be used
to interface with other Rust code easily.
For installation and documtoentation & linkage examples, refer to the documentation.
Rustmex v0.6 constitutes a major redesign of the crate. It has been broken up into a set of crates, such that each crate is compilable separately; feature flags are no longer required for Rustmex itself to compile. However, the easiest installation method is still to use feature flags to select the appropriate backend; confer to the documentation of the backend module for instructions. The 'normal' user facing API of Rustmex should however still mostly be the same as before; only the internals have changed.
This section contains some examples of how Rustmex can be used. Note however that these are not tested, since testing MEX functions involve starting a Matlab/Octave interpreter, and so this cannot be done automatically. Future versions of Rustmex will come with runnable examples.
That being said, each MEX function file has an entrypoint called mexFunction
. This is a
C FFI function, which, preferably, you do not want to write yourself. Instead, rustmex
provides the entrypoint macro; a macro to mark your Rust entrypoint with. For example:
```rust,ignore
use rustmex::prelude::*;
fn hello_world(lhs: Lhs, rhs: Rhs) -> rustmex::Result<()> { println!("Hello Matlab!"); Ok(()) } ```
Note that this example mirrors the definition of mexFunction
itself: Matlab has already
allocated a return value array, you just need to place your results into it.
The FromMatlabError
is for when you want to convert an mxArray into a more Rusty data
type. These conversions are not infallible: Matlab is dynamically typed, and the provided
mxArray
must have the same type and size as the type we want to convert it into.
As a more convoluted example: ```rust,ignore use rustmex::prelude::*;
fn euclideanlength(lhs: Lhs, rhs: Rhs) -> rustmex::Result<()> { let v: &[f64] = rhs .get(0) .errorifmissing("euclideanlength:missinginput", "Missing input vector to compute the length of")? .dataslice()?;
// I recommend to only execute your planned computation once you're sure it
// actually needs to be computed — it's a bit of a waste to compute an expensive
// result without somewhere to return it to.
if let Some(ret) = lhs.get_mut(0) {
ret.replace(v.iter().map(|x|x*x).sqrt().to_matlab());
}
Ok(())
} ```
This example computes the Euclidean length of an input vector. Note that type annotations
are (almost always) needed for the return type of data_slice()
and from_matlab()
.
Regarding [FromMatlab
][convert::FromMatlab
], this library also supports building
NDarrays from mxArrays. It will ensure that NDarray understands the data the same way
matlab does. For example, the following prints out a debug representation of the array:
```rust,ignore
use rustmex::prelude::*;
use ndarray::ArrayViewD;
fn displaymatrix(lhs: Lhs, rhs: Rhs) -> rustmex::Result<()> {
if let Some(mx) = rhs.get(0) {
let mat = ArrayViewD
Calling back into Matlab is also supported. For example, to compute the square
root of the sum of squares (i.e. nd-pythagoras):
matlab
% Call Rust MEX file
x = rusty_fn_call(@(x) sqrt(sum(x.^2)), 1:10)
```rust,ignore
use rustmex::prelude::*
use rustmex::function::Function;
fn rustyfncall(lhslice: rustmex::Lhs, rhslice: rustmex::Rhs) -> rustmex::Result<()> {
let f = rhslice
.get(0)
.error_if_missing("rusthello:no_fn", "Didn't get a function")?
.to_rust::<Function<_>>()?;
if let Some(r) = lhslice.get_mut(0) {
// Just forward the remaining arguments
let mut results: Box<[Option<MxArray>; 1]> = f.call(&rhslice[1..]).unwrap();
let v = results[0].take().unwrap();
r.replace(v);
};
return Ok(());
}
prints:
text
x = 19.621
```
If you assume something about the data you receive, but it might not yet be in the right
shape, you might want to reshape. Rustmex enables ergonomically reshaping data: you can
apply the ?
operator on a Result
with a ShapeError
in functions which return a
rustmex::Result
:
```rust,ignore
use rustmex::prelude::*;
use ndarray::{ArrayViewD, Ix2};
fn displaymatrix(lhs: Lhs, rhs: Rhs) -> rustmex::Result<()> {
if let Some(mx) = rhs.get(0) {
let mat = ArrayViewD
This is licensed to you under the Mozilla Public License, version 2. You can the licence in the LICENCE file in this project's source tree root folder.