Skip to content

Rust — FFI / Native Artifacts

nnrp-ffi exposes Rust-owned protocol and runtime behavior through a C-compatible ABI for Python, C#, Unity, Node native loaders, and future language bindings. Preview4 keeps the FFI boundary coarse: callers work through handles, events, and owned buffers instead of crossing the ABI for every small field.

Cargo

toml
[dependencies]
nnrp-ffi = "1.0.0-preview.4.0"

Native Artifact Shape

Preview4 publishes transport-scoped native artifacts. The role package decides whether it is a client or server at runtime; the artifact name tells you which transport implementation it contains.

TransportArtifact family
TCPnnrp-ffi-transport-tcp-native-<platform>-1.0.0-preview.4.0.zip
QUICnnrp-ffi-transport-quic-native-<platform>-1.0.0-preview.4.0.zip
IPCnnrp-ffi-transport-ipc-native-<platform>-1.0.0-preview.4.0.zip
WebSocketnnrp-ffi-transport-websocket-native-<platform>-1.0.0-preview.4.0.zip

Each package contains the native library, nnrp_ffi.h, and a manifest that declares platform, architecture, transport, library name, and exported symbols. Downstream SDKs should validate the manifest before loading the library.

ABI Types

TypeDescription
NnrpProtocolVersionCurrent major version and wire format.
NnrpHandleTyped handle with kind, id, generation, and flags.
NnrpBufferViewBorrowed byte slice valid only during the call.
NnrpFfiStatusStatus code, error family, protocol error, and detail code.
NnrpFfiDiagnosticStatus plus related connection/session/operation/frame ids.
NnrpEventCallback/polling event with handles, message type, frame id, owned payload handle/view, and diagnostics.

Non-empty buffer views must use non-null pointers. A non-empty runtime-frame event owns its payload through payload_owner. Bindings copy the payload and call nnrp_buffer_release(payload_owner) exactly once before returning an application event. A callback may inspect the view only during the callback; it still releases the owner after copying.

Runtime Requests

RequestPurpose
NnrpClientConnectRequestCreates a client connection handle.
NnrpSessionOpenRequestOpens a client session.
NnrpSubmitRequestSubmits one operation.
NnrpClientCancelRequestCancels client work.
NnrpServerBindRequestCreates a server handle.
NnrpServerAcceptRequestAccepts a server session.
NnrpServerReceiveSubmitRequestReceives a submit and creates an operation handle.
NnrpServerSendResultRequestSends result bytes.
NnrpControlRequestSends or validates generic control-plane frames.
NnrpRuntimeFrameSendRequestSends one typed Preview4 control, object, or cache frame through a session or operation handle. Fields are handle, message_type, frame_id, and payload.

NnrpRuntimeFrameSendRequest.payload contains the complete encoded metadata and declared tail. nnrp_runtime_frame_send validates the message type, metadata layout, declared lengths, handle scope, and client/server direction in one call. It snapshots the payload before returning; no queued event aliases caller-owned memory.

Exported Functions

FunctionDescription
nnrp_current_protocol_versionReturns the current protocol version.
nnrp_client_connectCreates a client connection handle.
nnrp_client_open_sessionCreates a client session handle.
nnrp_client_submitSubmits one operation and enqueues an event.
nnrp_client_cancelEnqueues cancel/drop-related events.
nnrp_client_await_eventPolls one event from a connection/session queue.
nnrp_client_closeCloses a client session.
nnrp_server_bindCreates a server handle.
nnrp_server_acceptCreates a server session handle.
nnrp_server_receive_submitReceives submit and creates an operation handle.
nnrp_server_send_resultEnqueues result output.
nnrp_server_send_flow_updateEnqueues flow-control output.
nnrp_server_closeCloses a server session.
nnrp_controlValidates and enqueues a generic control request.
nnrp_runtime_frame_sendRole-neutral coarse send path for Preview4 control, object, and cache frames.
nnrp_dispatch_eventDelivers one borrowed event through a callback.

nnrp_control remains an ABI-level compatibility primitive for non-Preview4 control codes inside Rust-owned integrations. SDK public APIs use nnrp_runtime_frame_send; they must not expose raw control-code routing as the normal application path.

C# P/Invoke Example

csharp
[LibraryImport("nnrp_ffi", EntryPoint = "nnrp_current_protocol_version")]
public static partial NnrpProtocolVersion CurrentProtocolVersion();

[StructLayout(LayoutKind.Sequential)]
public struct NnrpProtocolVersion
{
    public byte Major;
    public byte WireFormat;
}

Python ctypes Example

python
import ctypes

class NnrpProtocolVersion(ctypes.Structure):
    _fields_ = [("major", ctypes.c_uint8), ("wire_format", ctypes.c_uint8)]

lib = ctypes.CDLL("./libnnrp_ffi.so")
lib.nnrp_current_protocol_version.restype = NnrpProtocolVersion
version = lib.nnrp_current_protocol_version()

Boundary Rules

WARNING

  1. Native artifacts are transport-scoped. Do not treat client/server role packages as hidden native transport bundles.
  2. Browser SDKs use nnrp-wasm; they do not load .dll, .so, or .dylib files.
  3. Keep FFI calls coarse. Use handles and event polling/callbacks instead of adding one ABI call per Rust struct field.

NNRP Documentation