FFI Macro
The bbx_plugin_ffi! macro generates C FFI exports for a PluginDsp implementation.
Usage
#![allow(unused)] fn main() { use bbx_plugin::{PluginDsp, bbx_plugin_ffi}; pub struct MyPlugin { /* ... */ } impl PluginDsp for MyPlugin { /* ... */ } // Generate all FFI functions bbx_plugin_ffi!(MyPlugin); }
Generated Functions
The macro generates these extern "C" functions:
bbx_graph_create
BbxGraph* bbx_graph_create(void);
Creates a new DSP instance. Returns NULL on allocation failure.
bbx_graph_destroy
void bbx_graph_destroy(BbxGraph* handle);
Destroys the DSP instance. Safe to call with NULL.
bbx_graph_prepare
BbxError bbx_graph_prepare(
BbxGraph* handle,
double sample_rate,
uint32_t buffer_size,
uint32_t num_channels
);
Prepares for playback. Calls PluginDsp::prepare().
bbx_graph_reset
BbxError bbx_graph_reset(BbxGraph* handle);
Resets DSP state. Calls PluginDsp::reset().
bbx_graph_process
void bbx_graph_process(
BbxGraph* handle,
const float* const* inputs,
float* const* outputs,
uint32_t num_channels,
uint32_t num_samples,
const float* params,
uint32_t num_params
);
Processes audio. Calls PluginDsp::apply_parameters() then PluginDsp::process().
Internal Types
BbxGraph
Opaque handle to the Rust DSP:
#![allow(unused)] fn main() { #[repr(C)] pub struct BbxGraph { _private: [u8; 0], } }
Never dereference - it's a type-erased pointer to GraphInner<T>.
BbxError
Error codes:
#![allow(unused)] fn main() { #[repr(C)] pub enum BbxError { Ok = 0, NullPointer = 1, InvalidParameter = 2, InvalidBufferSize = 3, GraphNotPrepared = 4, AllocationFailed = 5, } }
Macro Expansion
The macro expands to roughly:
#![allow(unused)] fn main() { type PluginGraphInner = GraphInner<MyPlugin>; #[no_mangle] pub extern "C" fn bbx_graph_create() -> *mut BbxGraph { let inner = Box::new(PluginGraphInner::new()); handle_from_graph(inner) } #[no_mangle] pub extern "C" fn bbx_graph_destroy(handle: *mut BbxGraph) { if !handle.is_null() { unsafe { drop(Box::from_raw(handle as *mut PluginGraphInner)); } } } // ... other functions }
Safety
The macro handles:
- Null pointer checks
- Parameter validation
- Safe type conversions
- Memory ownership transfer
Custom Function Names
Currently, function names are fixed (bbx_graph_*). For custom names, you would need to write the FFI layer manually.