reflow_rt_capi
C ABI bindings for the Reflow runtime — the native surface consumed by non-Rust SDKs.
Rust users should depend on
reflow_rtdirectly. This crate exists so that SDKs in other languages share a single canonical ABI: Go viacgo, other ecosystems either bind the.hdirectly or wrap it in an idiomatic layer.
What it provides
- A stable, C-compatible ABI around
reflow_rt: network lifecycle, graph construction / loading, event streaming. cdylib+staticlibbuild artifacts so consumers can dynamically link or bundle the runtime.- Auto-generated
include/reflow_rt.h(viacbindgen).
Building
# Regular build — produces libreflow_rt_capi.{dylib,so,dll} + .a
# Regenerate the C header (requires the optional cbindgen build-dep)
The header lands at include/reflow_rt.h.
Conventions
All details are in src/lib.rs; the short version:
- Handles are opaque pointers (
rfl_network*,rfl_graph*,rfl_events*). Every*_new/*_loadhas a matching*_freethat is NULL-safe. - Return codes use the
rfl_statusenum; out-parameters are written on success. - Strings owned by the library are freed with
rfl_string_free. Never pass them tofree(3). - Error messages are thread-local; retrieve with
rfl_last_error_messageafter a failing call. - Threading: all handles are
Send + Sync; the crate lazily spins up a shared tokio multi-thread runtime on first use.
Current surface (v0.2)
Graph lifecycle + builder
rfl_graph* ;
rfl_graph* ;
void ;
char* ; /* reverse of load_json */
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
Network lifecycle + builder
rfl_network* ;
rfl_network* ; /* consumes the graph */
rfl_status ;
rfl_status ;
void ;
rfl_status ;
rfl_status ;
rfl_status ;
Event stream
rfl_events* ;
rfl_status ;
void ;
Misc
char* ;
char* ;
void ;
void ;
Callback-driven actors
Language SDKs can register native functions as actors. The runtime calls
them on every tick with a per-call rfl_actor_ctx* that exposes inputs,
config, state, and an emitter.
typedef enum ;
typedef void ;
rfl_actor* ; /* may be NULL */
void ;
rfl_status ;
Inside the callback (all returned strings are rfl_string_free-owned):
int ;
char* ;
char* ;
char* ;
rfl_status ;
rfl_status ;
Threading: callbacks run on a tokio worker. Language SDKs must arrange
their own synchronization (Node ThreadSafeFunction, Python GIL acquire,
JNI AttachCurrentThread, etc.).
user_data_drop fires exactly once, when the last reference to the actor
is released by the runtime — use it to release your GC root.
Typed messages
Skip the JSON tax for hot paths. rfl_message* is an opaque handle; pass
it to rfl_ctx_emit_message or rfl_ctx_take_input_message on the way
in and out.
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ;
rfl_message* ; /* fallback */
rfl_message_kind ;
int ;
int ;
int ;
char* ; /* rfl_string_free */
char* ; /* rfl_string_free */
int ;
void ;
rfl_status ; /* transfers ownership */
rfl_message* ;
Streams
Producer + consumer sides for Message::StreamHandle. Frames travel
through bounded flume channels; the message carries only the handle.
rfl_stream* ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_status ;
rfl_message* ; /* consumes, emit via rfl_ctx_emit_message */
void ;
rfl_stream_recv* ; /* one-shot */
rfl_status ;
void ;
Subgraph builder
For subgraphs whose referenced components aren't all in the bundled catalog (e.g. callback actors registered by the SDK):
rfl_subgraph_builder* ;
rfl_status ; /* transfers ownership */
rfl_status ;
rfl_actor* ; /* consumes builder */
void ;
NetworkConfig
rfl_network_new_with_config(const char* json) — parse a serialized
NetworkConfig. Default is still available via rfl_network_new().
Template catalog + subgraph (gated on the components feature)
Enabled by default; compile with --no-default-features to drop
reflow_components for a thinner shared library.
/* Bundled component instantiation */
rfl_actor* ;
char* ; /* JSON array of ids */
/* Subgraph embedding — resolves referenced components from the catalog */
rfl_actor* ;
All three return an rfl_actor* you can hand to
rfl_network_register_actor. This is how a non-Rust SDK registers the
bundled standard library (~300 templates) and composes graph exports as
first-class subgraph nodes.
Not yet in the ABI
- Structured event types — events currently arrive as JSON via
rfl_events_recv. Could be promoted to anrfl_event*handle with typed accessors; deferred until an SDK asks. - Graph introspection without JSON round-trip — today SDKs call
rfl_graph_to_jsonand parse client-side. Fine for cold paths; not fine for frequent reads. Could addrfl_graph_node_ids,rfl_graph_node_component,rfl_graph_connectionswhen that's a real hotspot. - Template metadata introspection — port shapes, description, config schema. Currently accessible only by instantiating the actor or consulting the published catalog docs.
License
MIT OR Apache-2.0.