# Rustmex
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.
## Design and Internals
### Ergonomics
The design of the library consists of three levels:
1. The Raw FFI level: the C FFI definitions
2. The wrapped mex level: functionality wrapping the raw level for a more ergonomic and
safe Rust interface
3. Top level: Wrapping the mex level, providing easy conversions to and from mxArrays.
It is recommended to write against the level which supports your features. If Rustmex
does not implement functionality you need, the lower levels are still available for that.
### API's
Rustmex wraps the bindings exposed by Matlab (pre and post 2017b) and GNU/Octave. The
features these bindings provide are all slightly different, so select one via a cargo
feature. These are:
- `matlab_interleaved`: Matlab, release 2018a and later, with the interleaved complex
API;
- `matlab_separated`: Matlab, release 2017b and earlier, with the separate real and
complex parts of mxArrays;
- `octave`: for GNU/Octave. (uses the same representation as matlab_separated)
Some of these targets also use symbol versioning, so _e.g._ `mxCreateNumericArray` is
actually `mxCreateNumericArray_800` for the matlab_interleaved API. For ease of use,
rustmex renames (`pub use $x_$v as $x`) these symbols to all have the same name in
[mex::raw].
When Rustmex is compiled for an API which represents complex values with two arrays,
slightly different implementations for data conversions are used. Since most Rust code
assumes that complex values are interleaved (i.e., the real and imaginary parts of the
value are stored next to eachother in memory) this might cause a lot of copying on the
interface.
_See also_ <https://nl.mathworks.com/help/matlab/matlab_external/matlab-support-for-interleaved-complex.html>.
### Memory Management
The Mex API has a few quirks when it comes to memory management. In particular,
allocations made via `mxMalloc` are, by default, deallocated when the MEX function
returns. This causes problems when some part of Rust code assumes that they are
responsible for deallocating the memory and assuming it is still after. Rustmex therefore
marks all allocations as persistent via `mexMakeMemoryPersistent`. _See also_
[`mex::alloc::mxAlloc`].
## TODO
- Structs and Objects
- [ ] From/To `Array<HashMap<Field, Value>>`
- [ ] From/To Rust struct via proc-macro?
## Licence
Work by Niels ter Meer 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.
## Authors
- Niels ter Meer (maintainer) <[termeerniels@gmail.com](mailto:termeerniels@gmail.com)>