Native Extensions
A native extension is a Rust library built against the resonon-ext crate. Writing and shipping one
is covered in Ship a Native Extension.
Attribute macros
Section titled “Attribute macros”All come from use resonon_ext::prelude::*;.
| Macro | On | Makes |
|---|---|---|
#[ext_fn] | a function | a function resonon can call |
#[ext_class] | a struct | a class whose instances resonon holds as opaque handles |
#[ext_new] | a function returning the class | the class’s constructor |
#[ext_method(Class)] | a function whose first parameter is &Class or &mut Class | a method; &Class reads, &mut Class writes |
ext_fn, ext_new and ext_method take an optional doc = "…", which resonon pkg inspect
prints.
resonon_extension!
Section titled “resonon_extension!”resonon_extension! { name: "my_ext", functions: [double, stepper_new, stepper_next], classes: [Stepper]}| Field | Value |
|---|---|
name | the extension name that __ext dispatches on |
functions | every ext_fn, ext_new and ext_method |
classes | every ext_class; may be left out when there are none |
A class missing from classes leaks its instances: the handle cleanup the runtime calls is
generated only for the classes listed there.
The Rust types a function or method can take and return, and the resonon value each one carries across the boundary:
| Resonon value | ExtValue variant | Rust parameter | Rust return |
|---|---|---|---|
42, 3.14 | Number(f64) | f64 | f64 |
A note, C4 | Note(f64) | f64, the fractional MIDI pitch | — (an f64 returns a Number) |
true, false | Boolean(bool) | bool | bool |
"hello" | String | &str (borrowed, read-only) or String (owned) | String |
#[1, 2, 3] | Array | Vec<f64>, an array of numbers | Vec<f64> |
NUL | Nul | — | (), no return value |
_ (rest) | Rest | — | — |
An #[ext_class] instance | Handle(u64) | — | — |
Any other Rust type is a compile error that names the supported ones. &str cannot be returned:
return String instead.
Calls from resonon
Section titled “Calls from resonon”| Call | Does |
|---|---|
__ext(extension, function, ...args) | calls function of the extension named extension, loading it on first use |
reload_ext(extension) | unloads the extension and loads its library again; fails while an object from it is alive |
Boundary rules
Section titled “Boundary rules”| Rule | |
|---|---|
| Thread | Every call runs on the interpreter thread, never on the audio thread. The library is loaded on its first call. |
| Panics | Functions generated by ext_fn, ext_new and ext_method catch a panic and return it as a resonon error carrying the panic message. An exported function written by hand, or in another language, must catch its own panics and return a non-zero code with an ExtValue::Error; a panic that unwinds across the boundary aborts the process. |
| Handles | A handle is valid only in the extension that made it. Passing it to another extension is an error. |
| Locking | Each class has one lock, covering all its instances. A call into a class waits for any other call into it to finish. |
| Returned values | Strings and arrays are copied across the boundary. Do not return a pointer to memory the extension keeps using. |
| Allocator | The default Rust allocator. A custom #[global_allocator] is not supported. |
| Trust | An extension is not sandboxed: it runs with the process’s rights. resonon pkg inspect loads it. |
Library files
Section titled “Library files”The extension named my_ext is looked for in the bin/ directory of the package my-ext or
my_ext: the current project if it is that package, then the packages under ./lib, then those
under ./dependencies. In each, the platform build wins over the generic one:
bin/<name>-<os>-<arch>.<ext>, e.g.my_ext-macos-aarch64.dylib, written byresonon build --distbin/<name>.<ext>, e.g.my_ext.dylib, written byresonon build
<ext> is dylib, so or dll. - in a name is read as _.
A package’s module is bound under its directory name with - changed to _: use "my-ext";
binds my_ext. That name and the name in resonon_extension! are separate; the scaffold keeps
them the same.
Related
Section titled “Related”- resonon.toml — the
[native]section - Native Extensions: Safety & Threading — what an extension may and may not do